🎉 Welcome to PyVerse! Start Learning Today

Lambda Functions and List Comprehensions

Audience: Grade 8–9 students with intermediate Python skills

Goal: Write less code while doing more, by mastering small anonymous functions (lambdas) and powerful one-liners for building lists (comprehensions).

Why this matters

  • You'll clean, reshape, and sort data in a few lines.
  • You'll write code that's both faster and easier to read—when used wisely.
  • These tools show up everywhere: data science, web backends, and coding interviews.

Part 1 — Lambda Functions

What is a lambda?

  • A lambda is a tiny, anonymous function defined in one expression.
  • Syntax: lambda arguments: expression
  • It has no name (unless you assign it to a variable), and it must contain exactly one expression (no multi-line statements).

Examples

1) Basic math

square = lambda x: x * x print(square(5)) # 25 add = lambda a, b: a + b print(add(2, 3)) # 5

2) Sorting with a key function

names = ["alice", "Bob", "carol", "dave"] print(sorted(names, key=lambda s: s.lower())) # Case-insensitive sort full_names = ["Ada Lovelace", "Alan Turing", "Grace Hopper"] print(sorted(full_names, key=lambda n: n.split()[-1])) # Sort by last name

3) Sorting by multiple criteria

students = [ {"name": "Ava", "score": 91}, {"name": "Ben", "score": 91}, {"name": "Cara", "score": 88}, ] # Highest score first, then name A→Z print(sorted(students, key=lambda s: (-s["score"], s["name"])))

4) Pair with map/filter

nums = [1, 2, 3, 4, 5] print(list(map(lambda x: x * 2, nums))) # [2, 4, 6, 8, 10] print(list(filter(lambda x: x % 2 == 0, nums))) # [2, 4]

Tip: Often, list comprehensions are clearer than map/filter with lambda. See Part 2.

Limitations and tips

  • One expression only. No assignments, loops, or multiple statements inside.
  • Use lambdas for short, throwaway functions (like keys for sorted).
  • For anything complex or reused, define a normal def function with a name and docstring for readability.

Advanced: closures and the "late binding" gotcha

Lambdas remember variables from outer scopes. But be careful inside loops:

funcs = [] for i in range(3): funcs.append(lambda: i) # Captures the same 'i' print([f() for f in funcs]) # [2, 2, 2] (surprise!) # Fix by freezing the current value using a default argument: funcs = [] for i in range(3): funcs.append(lambda i=i: i) print([f() for f in funcs]) # [0, 1, 2]

Part 2 — List Comprehensions

What is a list comprehension?

  • A fast way to build lists using a single readable expression.
  • Syntax: [expression for item in iterable if condition]
  • Reads like: "Make a list of expression for each item, but only if condition."

Basic examples

1) Transform items

nums = [1, 2, 3, 4] squares = [n*n for n in nums] print(squares) # [1, 4, 9, 16]

2) Filter items

evens = [n for n in nums if n % 2 == 0] print(evens) # [2, 4]

3) Conditional expression (if/else) inside the expression

labels = ["even" if n % 2 == 0 else "odd" for n in nums] print(labels) # ['odd', 'even', 'odd', 'even']

4) Nested loops (flatten a 2D list)

grid = [[1, 2], [3, 4], [5]] flat = [x for row in grid for x in row] print(flat) # [1, 2, 3, 4, 5]

Map/filter equivalents

Map with lambda:

list(map(lambda n: n*n, nums))

Same with comprehension (usually clearer):

[n*n for n in nums]

Filter with lambda:

list(filter(lambda n: n % 2 == 0, nums))

Same with comprehension:

[n for n in nums if n % 2 == 0]

More comprehensions

Set comprehension (unique results)

names = ["ann", "bob", "ann", "cara"] unique_lengths = {len(n) for n in names} print(unique_lengths) # {3, 4}

Dict comprehension

scores = {"ann": 81, "bob": 95, "cara": 88} grade = {name: ("A" if s >= 90 else "B" if s >= 80 else "C") for name, s in scores.items()} print(grade) # {'ann': 'B', 'bob': 'A', 'cara': 'B'}

Generator expression (like list comprehension, but lazy)

big = (n*n for n in range(10_000_000)) # uses little memory print(next(big), next(big), next(big)) # 0 1 4

Performance and readability

  • List comprehensions are often faster than building lists with append in a loop.
  • Rule of thumb: if it fits comfortably on one line and is easy to read, use a comprehension. Otherwise, use a normal loop for clarity.
  • In Python 3, the variable used inside a comprehension does not leak into the outer scope.

When to use what

  • Use lambda mostly as a short key function (sortedminmax) or with small map/filter tasks.
  • Prefer list comprehensions to map/filter for clarity—unless a named function already exists (e.g., map(str, items)).

Hands-on Practice Snippets

1) Case-insensitive unique words, sorted by length then alphabetically

text = "Python makes powerful patterns possible" words = {w.lower() for w in text.split()} # unique, lowercased result = sorted(words, key=lambda w: (len(w), w)) print(result)

2) Top 3 longest lines from a file (pretend we have lines)

lines = ["short", "a bit longer", "the longest line here", "mid"] top3 = sorted(lines, key=lambda s: len(s), reverse=True)[:3] print(top3)

3) Flatten, then filter

matrix = [[1, 2, 3], [4, 5], [6, 7, 8]] even_flat = [x for row in matrix for x in row if x % 2 == 0] print(even_flat) # [2, 4, 6, 8]

Mini Project — Student Scoreboard Cleaner and Analyzer

You'll clean messy student data, compute grades, and produce a sorted leaderboard using lambdas and comprehensions.

Starter data

raw = [ " alice , 88 ", "Bob,95", "cara, 105", # over 100, should clamp to 100 "Dan,-3", # negative, should clamp to 0 " , 70", # missing name -> drop "Eve, ninety", # non-numeric -> drop "frank, 72" ]

Tasks

  1. Parse each line into (name, score).
    • Strip spaces, title-case the name.
    • Convert score to int; if it fails, drop the record.
  2. Clamp scores to the range [0, 100].
  3. Curve scores by +5 but not above 100.
  4. Assign letter grades: A (≥90), B (80–89), C (70–79), D (60–69), F (<60).
  5. Sort by score (desc), then name (asc), using a lambda key.
  6. Print the top 3 and a summary (count, average score).

Hint plan

  • Use a comprehension to parse and filter invalid lines.
  • Use min/max or clamp with: max(0, min(100, score))
  • Use a dict/list comprehension to build final structures.

Solution walkthrough

Step 1–2: Parse and clean

def try_parse_record(line): if "," not in line: return None name_part, score_part = line.split(",", 1) name = name_part.strip().title() score_str = score_part.strip() if not name: return None try: score = int(score_str) except ValueError: return None # clamp to [0, 100] score = max(0, min(100, score)) return {"name": name, "score": score} cleaned = [rec for rec in (try_parse_record(line) for line in raw) if rec is not None] print(cleaned)

Step 3: Curve scores (use a comprehension)

curved = [{**rec, "score": min(100, rec["score"] + 5)} for rec in cleaned]

Step 4: Letter grades

def letter(score): return ( "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "D" if score >= 60 else "F" ) graded = [{**rec, "grade": letter(rec["score"])} for rec in curved]

Step 5: Sort using a lambda key

leaderboard = sorted(graded, key=lambda r: (-r["score"], r["name"])) for row in leaderboard: print(row)

Step 6: Top 3 and summary

top3 = leaderboard[:3] print("Top 3:") for r in top3: print(f'{r["name"]}: {r["score"]} ({r["grade"]})') avg = sum(r["score"] for r in leaderboard) / len(leaderboard) print(f"Total students: {len(leaderboard)}") print(f"Average score: {avg:.1f}")

Expected output idea (will vary by data)

  • Names cleaned (Alice, Bob, Cara, Dan, Frank)
  • Scores clamped and curved
  • Sorted by score desc, then name
  • Average printed

Extension challenges

  • Add pass/fail rate using a comprehension.
  • Group by grade letter into a dict: {grade: [names...]} via dict comprehension.
  • Export to CSV string lines like "Name,Score,Grade" using a list comprehension.

Common Pitfalls and Pro Tips

  • Don't overuse lambdas. If it gets long or you need comments, use def.
  • For big pipelines, prefer comprehensions or generator expressions over building large temporary lists.
  • Remember: in Python 3, comprehension variables don't leak to outer scope.
  • For complex sorts, use a lambda that returns a tuple: key=lambda x: (primary, secondary, ...).
  • If you hit the late-binding trap in lambdas inside loops, freeze variables with defaults: lambda v=v: v.

Summary

  • Lambda functions are tiny, anonymous functions perfect for short tasks like sort keys or simple transforms.
  • List comprehensions build lists quickly and readably; they can transform, filter, and even nest loops in one expression.
  • Prefer list comprehensions over map/filter for readability, unless using an existing function like str or int.
  • Combined, these tools help you clean data, sort smartly, and compute results in fewer lines—skills used in real-world Python every day.

Practice prompt

Given a list of movie dicts with "title", "year", "rating", build:

  1. A list of titles for movies after 2015 with rating ≥ 8.0, sorted by rating desc.
  2. A dict mapping title → "Classic" if year < 2000 else "Modern".

Use one lambda for sorting and comprehensions for the rest.

Loading quizzes...