Lambda functions for simple operations like getting an attribute or adding numbers add visual noise and reduce readability. The operator module provides efficient, named functions for built-in operators, making sorting keys and functional operations clearer and faster.

operator functions Named functions that perform the same operations as Python operators (+, -, [], .) but can be passed as arguments to other functions.

Itemgetter

Extract items by key or index:

numbers
itemgetter.py
Replay: real traced execution (multi-file project)
"""operator.itemgetter examples"""

import operator

# Basic itemgetter
print("Basic itemgetter:")

# Get single item
get_first = operator.itemgetter(0)
numbers = [10, 20, 30, 40]

print(f"get_first({numbers}): {get_first(numbers)}")

# Get by key
data = {'name': 'Alice', 'age': 30}
get_name = operator.itemgetter('name')
print(f"get_name({data}): {get_name(data)}")

# Multiple items
print("\nMultiple items:")

# Get multiple indices
get_items = operator.itemgetter(0, 2, 4)
letters = ['a', 'b', 'c', 'd', 'e']

result = get_items(letters)
print(f"get_items({letters}): {result}")

# Multiple keys
get_info = operator.itemgetter('name', 'age')
person = {'name': 'Bob', 'age': 25, 'city': 'NYC'}
print(f"get_info: {get_info(person)}")

# Sorting lists
print("\nSorting lists:")

students = [
    {'name': 'Charlie', 'grade': 85},
    {'name': 'Alice', 'grade': 92},
    {'name': 'Bob', 'grade': 78}
]

# Sort by grade
sorted_by_grade = sorted(students, key=operator.itemgetter('grade'))
print("Sorted by grade:")
for s in sorted_by_grade:
    print(f"  {s}")

# Sort by name
sorted_by_name = sorted(students, key=operator.itemgetter('name'))
print("\nSorted by name:")
for s in sorted_by_name:
    print(f"  {s}")

# Nested sorting
print("\nNested sorting:")

data = [
    {'name': 'Alice', 'scores': [85, 90]},
    {'name': 'Bob', 'scores': [92, 88]},
    {'name': 'Charlie', 'scores': [78, 95]}
]

# Sort by first score
sorted_data = sorted(data,
    key=lambda x: operator.itemgetter(0)(x['scores']))

print("Sorted by first score:")
for d in sorted_data:
    print(f"  {d}")

# With tuples
print("\nWith tuples:")

records = [
    ('Alice', 30, 'NYC'),
    ('Bob', 25, 'LA'),
    ('Charlie', 35, 'Chicago')
]

# Sort by age (index 1)
sorted_by_age = sorted(records, key=operator.itemgetter(1))
print("Sorted by age:")
for r in sorted_by_age:
    print(f"  {r}")

# Sort by multiple fields (city, then age)
sorted_multi = sorted(records, key=operator.itemgetter(2, 1))
print("\nSorted by city then age:")
for r in sorted_multi:
    print(f"  {r}")

# Map and filter
print("\nMap and filter:")

users = [
    {'id': 1, 'name': 'Alice', 'active': True},
    {'id': 2, 'name': 'Bob', 'active': False},
    {'id': 3, 'name': 'Charlie', 'active': True}
]

# Extract all names
names = list(map(operator.itemgetter('name'), users))
print(f"Names: {names}")

# Extract ids of active users
active_ids = [
    operator.itemgetter('id')(user)
    for user in users
    if user['active']
]
print(f"Active IDs: {active_ids}")

# Min/max
print("\nMin/max:")

products = [
    {'name': 'Widget', 'price': 29.99},
    {'name': 'Gadget', 'price': 49.99},
    {'name': 'Tool', 'price': 19.99}
]

cheapest = min(products, key=operator.itemgetter('price'))
print(f"Cheapest: {cheapest}")

most_expensive = max(products, key=operator.itemgetter('price'))
print(f"Most expensive: {most_expensive}")

# Grouping
print("\nGrouping:")

from itertools import groupby

transactions = [
    {'category': 'food', 'amount': 50},
    {'category': 'transport', 'amount': 20},
    {'category': 'food', 'amount': 30},
    {'category': 'transport', 'amount': 15}
]

# Must sort first for groupby
transactions.sort(key=operator.itemgetter('category'))

for category, items in groupby(transactions,
                               key=operator.itemgetter('category')):
    total = sum(operator.itemgetter('amount')(item) for item in items)
    print(f"{category}: ${total}")

"""operator.itemgetter examples"""

import operator

# Basic itemgetter
print("Basic itemgetter:")

# Get single item
get_first = operator.itemgetter(0)
numbers = [5, 15, 25]

print(f"get_first({numbers}): {get_first(numbers)}")

# Get by key
data = {'name': 'Alice', 'age': 30}
get_name = operator.itemgetter('name')
print(f"get_name({data}): {get_name(data)}")

# Multiple items
print("\nMultiple items:")

# Get multiple indices
get_items = operator.itemgetter(0, 2, 4)
letters = ['a', 'b', 'c', 'd', 'e']

result = get_items(letters)
print(f"get_items({letters}): {result}")

# Multiple keys
get_info = operator.itemgetter('name', 'age')
person = {'name': 'Bob', 'age': 25, 'city': 'NYC'}
print(f"get_info: {get_info(person)}")

# Sorting lists
print("\nSorting lists:")

students = [
    {'name': 'Charlie', 'grade': 85},
    {'name': 'Alice', 'grade': 92},
    {'name': 'Bob', 'grade': 78}
]

# Sort by grade
sorted_by_grade = sorted(students, key=operator.itemgetter('grade'))
print("Sorted by grade:")
for s in sorted_by_grade:
    print(f"  {s}")

# Sort by name
sorted_by_name = sorted(students, key=operator.itemgetter('name'))
print("\nSorted by name:")
for s in sorted_by_name:
    print(f"  {s}")

# Nested sorting
print("\nNested sorting:")

data = [
    {'name': 'Alice', 'scores': [85, 90]},
    {'name': 'Bob', 'scores': [92, 88]},
    {'name': 'Charlie', 'scores': [78, 95]}
]

# Sort by first score
sorted_data = sorted(data,
    key=lambda x: operator.itemgetter(0)(x['scores']))

print("Sorted by first score:")
for d in sorted_data:
    print(f"  {d}")

# With tuples
print("\nWith tuples:")

records = [
    ('Alice', 30, 'NYC'),
    ('Bob', 25, 'LA'),
    ('Charlie', 35, 'Chicago')
]

# Sort by age (index 1)
sorted_by_age = sorted(records, key=operator.itemgetter(1))
print("Sorted by age:")
for r in sorted_by_age:
    print(f"  {r}")

# Sort by multiple fields (city, then age)
sorted_multi = sorted(records, key=operator.itemgetter(2, 1))
print("\nSorted by city then age:")
for r in sorted_multi:
    print(f"  {r}")

# Map and filter
print("\nMap and filter:")

users = [
    {'id': 1, 'name': 'Alice', 'active': True},
    {'id': 2, 'name': 'Bob', 'active': False},
    {'id': 3, 'name': 'Charlie', 'active': True}
]

# Extract all names
names = list(map(operator.itemgetter('name'), users))
print(f"Names: {names}")

# Extract ids of active users
active_ids = [
    operator.itemgetter('id')(user)
    for user in users
    if user['active']
]
print(f"Active IDs: {active_ids}")

# Min/max
print("\nMin/max:")

products = [
    {'name': 'Widget', 'price': 29.99},
    {'name': 'Gadget', 'price': 49.99},
    {'name': 'Tool', 'price': 19.99}
]

cheapest = min(products, key=operator.itemgetter('price'))
print(f"Cheapest: {cheapest}")

most_expensive = max(products, key=operator.itemgetter('price'))
print(f"Most expensive: {most_expensive}")

# Grouping
print("\nGrouping:")

from itertools import groupby

transactions = [
    {'category': 'food', 'amount': 50},
    {'category': 'transport', 'amount': 20},
    {'category': 'food', 'amount': 30},
    {'category': 'transport', 'amount': 15}
]

# Must sort first for groupby
transactions.sort(key=operator.itemgetter('category'))

for category, items in groupby(transactions,
                               key=operator.itemgetter('category')):
    total = sum(operator.itemgetter('amount')(item) for item in items)
    print(f"{category}: ${total}")

"""operator.itemgetter examples"""

import operator

# Basic itemgetter
print("Basic itemgetter:")

# Get single item
get_first = operator.itemgetter(0)
numbers = [100, 200, 300]

print(f"get_first({numbers}): {get_first(numbers)}")

# Get by key
data = {'name': 'Alice', 'age': 30}
get_name = operator.itemgetter('name')
print(f"get_name({data}): {get_name(data)}")

# Multiple items
print("\nMultiple items:")

# Get multiple indices
get_items = operator.itemgetter(0, 2, 4)
letters = ['a', 'b', 'c', 'd', 'e']

result = get_items(letters)
print(f"get_items({letters}): {result}")

# Multiple keys
get_info = operator.itemgetter('name', 'age')
person = {'name': 'Bob', 'age': 25, 'city': 'NYC'}
print(f"get_info: {get_info(person)}")

# Sorting lists
print("\nSorting lists:")

students = [
    {'name': 'Charlie', 'grade': 85},
    {'name': 'Alice', 'grade': 92},
    {'name': 'Bob', 'grade': 78}
]

# Sort by grade
sorted_by_grade = sorted(students, key=operator.itemgetter('grade'))
print("Sorted by grade:")
for s in sorted_by_grade:
    print(f"  {s}")

# Sort by name
sorted_by_name = sorted(students, key=operator.itemgetter('name'))
print("\nSorted by name:")
for s in sorted_by_name:
    print(f"  {s}")

# Nested sorting
print("\nNested sorting:")

data = [
    {'name': 'Alice', 'scores': [85, 90]},
    {'name': 'Bob', 'scores': [92, 88]},
    {'name': 'Charlie', 'scores': [78, 95]}
]

# Sort by first score
sorted_data = sorted(data,
    key=lambda x: operator.itemgetter(0)(x['scores']))

print("Sorted by first score:")
for d in sorted_data:
    print(f"  {d}")

# With tuples
print("\nWith tuples:")

records = [
    ('Alice', 30, 'NYC'),
    ('Bob', 25, 'LA'),
    ('Charlie', 35, 'Chicago')
]

# Sort by age (index 1)
sorted_by_age = sorted(records, key=operator.itemgetter(1))
print("Sorted by age:")
for r in sorted_by_age:
    print(f"  {r}")

# Sort by multiple fields (city, then age)
sorted_multi = sorted(records, key=operator.itemgetter(2, 1))
print("\nSorted by city then age:")
for r in sorted_multi:
    print(f"  {r}")

# Map and filter
print("\nMap and filter:")

users = [
    {'id': 1, 'name': 'Alice', 'active': True},
    {'id': 2, 'name': 'Bob', 'active': False},
    {'id': 3, 'name': 'Charlie', 'active': True}
]

# Extract all names
names = list(map(operator.itemgetter('name'), users))
print(f"Names: {names}")

# Extract ids of active users
active_ids = [
    operator.itemgetter('id')(user)
    for user in users
    if user['active']
]
print(f"Active IDs: {active_ids}")

# Min/max
print("\nMin/max:")

products = [
    {'name': 'Widget', 'price': 29.99},
    {'name': 'Gadget', 'price': 49.99},
    {'name': 'Tool', 'price': 19.99}
]

cheapest = min(products, key=operator.itemgetter('price'))
print(f"Cheapest: {cheapest}")

most_expensive = max(products, key=operator.itemgetter('price'))
print(f"Most expensive: {most_expensive}")

# Grouping
print("\nGrouping:")

from itertools import groupby

transactions = [
    {'category': 'food', 'amount': 50},
    {'category': 'transport', 'amount': 20},
    {'category': 'food', 'amount': 30},
    {'category': 'transport', 'amount': 15}
]

# Must sort first for groupby
transactions.sort(key=operator.itemgetter('category'))

for category, items in groupby(transactions,
                               key=operator.itemgetter('category')):
    total = sum(operator.itemgetter('amount')(item) for item in items)
    print(f"{category}: ${total}")

  1. get_first ← operator.itemgetter(0), numbers ← [10, 20, 30, 40]

    1"""operator.itemgetter examples"""23import operator45# Basic itemgetter6print("Basic itemgetter:")78# Get single item9get_first→ operator.itemgetter(0) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0)10numbers→ [10, 20, 30, 40] = [10, 20, 30, 40]  #@numbers=[5, 15, 25], [100, 200, 300]1112print(f"get_first({numbers[10, 20, 30, 40]}): {get_first(numbers)}")1314# Get by key15data→ {'name': 'Alice', 'age': 30} = {'name': 'Alice', 'age': 30}16get_name→ operator.itemgetter('name') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name')17print(f"get_name({data{'name': 'Alice', 'age': 30}}): {get_name(data)}")1819# Multiple items20print("\nMultiple items:")2122# Get multiple indices23get_items→ operator.itemgetter(0, 2, 4) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0, 2, 4)24letters→ ['a', 'b', 'c', 'd', 'e'] = ['a', 'b', 'c', 'd', 'e']2526result→ ('a', 'c', 'e') = get_items(letters['a', 'b', 'c', 'd', 'e'])27print(f"get_items({letters['a', 'b', 'c', 'd', 'e']}): {result('a', 'c', 'e')}")2829# Multiple keys30get_info→ operator.itemgetter('name', 'age') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name', 'age')31person→ {'name': 'Bob', 'age': 25, 'city': 'NYC'} = {'name': 'Bob', 'age': 25, 'city': 'NYC'}32print(f"get_info: {get_info(person{'name': 'Bob', 'age': 25, 'city': 'NYC'})}")3334# Sorting lists35print("\nSorting lists:")3637students→ [{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}] = [38    {'name': 'Charlie', 'grade': 85},39    {'name': 'Alice', 'grade': 92},40    {'name': 'Bob', 'grade': 78}41]4243# Sort by grade44sorted_by_grade→ [{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('grade'))45print("Sorted by grade:")46for s in sorted_by_grade:
    outputBasic itemgetter:
    get_first([10, 20, 30, 40]): 10
    get_name({'name': 'Alice', 'age': 30}): Alice
    
    Multiple items:
    get_items(['a', 'b', 'c', 'd', 'e']): ('a', 'c', 'e')
    get_info: ('Bob', 25)
    
    Sorting lists:
    Sorted by grade:
  2. for s in sorted_by_grade:

    pass 1 of 3
    45print("Sorted by grade:")46for s{'name': 'Bob', 'grade': 78} in sorted_by_grade[{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}]:47    print(f"  {s{'name': 'Bob', 'grade': 78}}")
    output  {'name': 'Bob', 'grade': 78}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Bob', 'grade': 78}
    2{'name': 'Charlie', 'grade': 85}
    3{'name': 'Alice', 'grade': 92}
  3. sorted_by_name ← [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]

    49# Sort by name50sorted_by_name→ [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'))51print("\nSorted by name:")52for s in sorted_by_name:
    output
    Sorted by name:
  4. for s in sorted_by_name:

    pass 1 of 3
    51print("\nSorted by name:")52for s{'name': 'Alice', 'grade': 92} in sorted_by_name[{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]:53    print(f"  {s{'name': 'Alice', 'grade': 92}}")
    output  {'name': 'Alice', 'grade': 92}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Alice', 'grade': 92}
    2{'name': 'Bob', 'grade': 78}
    3{'name': 'Charlie', 'grade': 85}
  5. data ← [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}]

    55# Nested sorting56print("\nNested sorting:")5758data→ [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}] = [59    {'name': 'Alice', 'scores': [85, 90]},60    {'name': 'Bob', 'scores': [92, 88]},61    {'name': 'Charlie', 'scores': [78, 95]}62]6364# Sort by first score65sorted_data→ [{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}] = sorted(data[{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}], 66    key=lambda x: operator.itemgetter(0)(x['scores']))6768print("Sorted by first score:")69for d in sorted_data:
    output
    Nested sorting:
    Sorted by first score:
  6. for d in sorted_data:

    pass 1 of 3
    68print("Sorted by first score:")69for d{'name': 'Charlie', 'scores': [78, 95]} in sorted_data[{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}]:70    print(f"  {d{'name': 'Charlie', 'scores': [78, 95]}}")
    output  {'name': 'Charlie', 'scores': [78, 95]}
    All 3 passes — pass 1 is the card above
    passd
    1{'name': 'Charlie', 'scores': [78, 95]}
    2{'name': 'Alice', 'scores': [85, 90]}
    3{'name': 'Bob', 'scores': [92, 88]}
  7. records ← [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')]

    72# With tuples73print("\nWith tuples:")7475records→ [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')] = [76    ('Alice', 30, 'NYC'),77    ('Bob', 25, 'LA'),78    ('Charlie', 35, 'Chicago')79]8081# Sort by age (index 1)82sorted_by_age→ [('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(1))83print("Sorted by age:")84for r in sorted_by_age:
    output
    With tuples:
    Sorted by age:
  8. for r in sorted_by_age:

    pass 1 of 3
    83print("Sorted by age:")84for r('Bob', 25, 'LA') in sorted_by_age[('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')]:85    print(f"  {r('Bob', 25, 'LA')}")
    output  ('Bob', 25, 'LA')
    All 3 passes — pass 1 is the card above
    passr
    1('Bob', 25, 'LA')
    2('Alice', 30, 'NYC')
    3('Charlie', 35, 'Chicago')
  9. sorted_multi ← [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]

    87# Sort by multiple fields (city, then age)88sorted_multi→ [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(2, 1))89print("\nSorted by city then age:")90for r in sorted_multi:
    output
    Sorted by city then age:
  10. for r in sorted_multi:

    pass 1 of 3
    89print("\nSorted by city then age:")90for r('Charlie', 35, 'Chicago') in sorted_multi[('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]:91    print(f"  {r('Charlie', 35, 'Chicago')}")
    output  ('Charlie', 35, 'Chicago')
    All 3 passes — pass 1 is the card above
    passr
    1('Charlie', 35, 'Chicago')
    2('Bob', 25, 'LA')
    3('Alice', 30, 'NYC')
  11. users ← [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]

    93# Map and filter94print("\nMap and filter:")9596users→ [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}] = [97    {'id': 1, 'name': 'Alice', 'active': True},98    {'id': 2, 'name': 'Bob', 'active': False},99    {'id': 3, 'name': 'Charlie', 'active': True}100]101102# Extract all names103names→ ['Alice', 'Bob', 'Charlie'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'), users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]))104print(f"Names: {names['Alice', 'Bob', 'Charlie']}")105106# Extract ids of active users107active_ids→ [1, 3] = [108    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('id')(user)109    for user in users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]110    if user['active'](empty)111]112print(f"Active IDs: {active_ids[1, 3]}")113114# Min/max115print("\nMin/max:")116117products→ [{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}] = [118    {'name': 'Widget', 'price': 29.99},119    {'name': 'Gadget', 'price': 49.99},120    {'name': 'Tool', 'price': 19.99}121]122123cheapest→ {'name': 'Tool', 'price': 19.99} = min(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))124print(f"Cheapest: {cheapest{'name': 'Tool', 'price': 19.99}}")125126most_expensive→ {'name': 'Gadget', 'price': 49.99} = max(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))127print(f"Most expensive: {most_expensive{'name': 'Gadget', 'price': 49.99}}")128129# Grouping130print("\nGrouping:")131132from itertools import groupby133134transactions→ [{'category': 'food', 'amount': 50}, {'category': 'transport', 'amount': 20}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 15}] = [135    {'category': 'food', 'amount': 50},136    {'category': 'transport', 'amount': 20},137    {'category': 'food', 'amount': 30},138    {'category': 'transport', 'amount': 15}139]140141# Must sort first for groupby142transactions→ [{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}].sort(key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category'))
    output
    Map and filter:
    Names: ['Alice', 'Bob', 'Charlie']
    Active IDs: [1, 3]
    
    Min/max:
    Cheapest: {'name': 'Tool', 'price': 19.99}
    Most expensive: {'name': 'Gadget', 'price': 49.99}
    
    Grouping:
  12. total ← 80

    pass 1 of 2
    144for categoryfood, items⟨_grouper A⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 80 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper A⟩)147    print(f"{categoryfood}: ${total80}")
    outputfood: $80
  13. total ← 35

    pass 2 of 2
    144for categorytransport, items⟨_grouper B⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 35 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper B⟩)147    print(f"{categorytransport}: ${total35}")
    outputtransport: $35
  1. get_first ← operator.itemgetter(0), numbers ← [5, 15, 25], data ← {'name': 'Alice', 'age': 30}

    1"""operator.itemgetter examples"""23import operator45# Basic itemgetter6print("Basic itemgetter:")78# Get single item9get_first→ operator.itemgetter(0) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0)10numbers→ [5, 15, 25] = [5, 15, 25]1112print(f"get_first({numbers[5, 15, 25]}): {get_first(numbers)}")1314# Get by key15data→ {'name': 'Alice', 'age': 30} = {'name': 'Alice', 'age': 30}16get_name→ operator.itemgetter('name') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name')17print(f"get_name({data{'name': 'Alice', 'age': 30}}): {get_name(data)}")1819# Multiple items20print("\nMultiple items:")2122# Get multiple indices23get_items→ operator.itemgetter(0, 2, 4) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0, 2, 4)24letters→ ['a', 'b', 'c', 'd', 'e'] = ['a', 'b', 'c', 'd', 'e']2526result→ ('a', 'c', 'e') = get_items(letters['a', 'b', 'c', 'd', 'e'])27print(f"get_items({letters['a', 'b', 'c', 'd', 'e']}): {result('a', 'c', 'e')}")2829# Multiple keys30get_info→ operator.itemgetter('name', 'age') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name', 'age')31person→ {'name': 'Bob', 'age': 25, 'city': 'NYC'} = {'name': 'Bob', 'age': 25, 'city': 'NYC'}32print(f"get_info: {get_info(person{'name': 'Bob', 'age': 25, 'city': 'NYC'})}")3334# Sorting lists35print("\nSorting lists:")3637students→ [{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}] = [38    {'name': 'Charlie', 'grade': 85},39    {'name': 'Alice', 'grade': 92},40    {'name': 'Bob', 'grade': 78}41]4243# Sort by grade44sorted_by_grade→ [{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('grade'))45print("Sorted by grade:")46for s in sorted_by_grade:
    outputBasic itemgetter:
    get_first([5, 15, 25]): 5
    get_name({'name': 'Alice', 'age': 30}): Alice
    
    Multiple items:
    get_items(['a', 'b', 'c', 'd', 'e']): ('a', 'c', 'e')
    get_info: ('Bob', 25)
    
    Sorting lists:
    Sorted by grade:
  2. for s in sorted_by_grade:

    pass 1 of 3
    45print("Sorted by grade:")46for s{'name': 'Bob', 'grade': 78} in sorted_by_grade[{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}]:47    print(f"  {s{'name': 'Bob', 'grade': 78}}")
    output  {'name': 'Bob', 'grade': 78}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Bob', 'grade': 78}
    2{'name': 'Charlie', 'grade': 85}
    3{'name': 'Alice', 'grade': 92}
  3. sorted_by_name ← [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]

    49# Sort by name50sorted_by_name→ [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'))51print("\nSorted by name:")52for s in sorted_by_name:
    output
    Sorted by name:
  4. for s in sorted_by_name:

    pass 1 of 3
    51print("\nSorted by name:")52for s{'name': 'Alice', 'grade': 92} in sorted_by_name[{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]:53    print(f"  {s{'name': 'Alice', 'grade': 92}}")
    output  {'name': 'Alice', 'grade': 92}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Alice', 'grade': 92}
    2{'name': 'Bob', 'grade': 78}
    3{'name': 'Charlie', 'grade': 85}
  5. data ← [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}]

    55# Nested sorting56print("\nNested sorting:")5758data→ [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}] = [59    {'name': 'Alice', 'scores': [85, 90]},60    {'name': 'Bob', 'scores': [92, 88]},61    {'name': 'Charlie', 'scores': [78, 95]}62]6364# Sort by first score65sorted_data→ [{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}] = sorted(data[{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}], 66    key=lambda x: operator.itemgetter(0)(x['scores']))6768print("Sorted by first score:")69for d in sorted_data:
    output
    Nested sorting:
    Sorted by first score:
  6. for d in sorted_data:

    pass 1 of 3
    68print("Sorted by first score:")69for d{'name': 'Charlie', 'scores': [78, 95]} in sorted_data[{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}]:70    print(f"  {d{'name': 'Charlie', 'scores': [78, 95]}}")
    output  {'name': 'Charlie', 'scores': [78, 95]}
    All 3 passes — pass 1 is the card above
    passd
    1{'name': 'Charlie', 'scores': [78, 95]}
    2{'name': 'Alice', 'scores': [85, 90]}
    3{'name': 'Bob', 'scores': [92, 88]}
  7. records ← [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')]

    72# With tuples73print("\nWith tuples:")7475records→ [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')] = [76    ('Alice', 30, 'NYC'),77    ('Bob', 25, 'LA'),78    ('Charlie', 35, 'Chicago')79]8081# Sort by age (index 1)82sorted_by_age→ [('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(1))83print("Sorted by age:")84for r in sorted_by_age:
    output
    With tuples:
    Sorted by age:
  8. for r in sorted_by_age:

    pass 1 of 3
    83print("Sorted by age:")84for r('Bob', 25, 'LA') in sorted_by_age[('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')]:85    print(f"  {r('Bob', 25, 'LA')}")
    output  ('Bob', 25, 'LA')
    All 3 passes — pass 1 is the card above
    passr
    1('Bob', 25, 'LA')
    2('Alice', 30, 'NYC')
    3('Charlie', 35, 'Chicago')
  9. sorted_multi ← [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]

    87# Sort by multiple fields (city, then age)88sorted_multi→ [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(2, 1))89print("\nSorted by city then age:")90for r in sorted_multi:
    output
    Sorted by city then age:
  10. for r in sorted_multi:

    pass 1 of 3
    89print("\nSorted by city then age:")90for r('Charlie', 35, 'Chicago') in sorted_multi[('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]:91    print(f"  {r('Charlie', 35, 'Chicago')}")
    output  ('Charlie', 35, 'Chicago')
    All 3 passes — pass 1 is the card above
    passr
    1('Charlie', 35, 'Chicago')
    2('Bob', 25, 'LA')
    3('Alice', 30, 'NYC')
  11. users ← [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]

    93# Map and filter94print("\nMap and filter:")9596users→ [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}] = [97    {'id': 1, 'name': 'Alice', 'active': True},98    {'id': 2, 'name': 'Bob', 'active': False},99    {'id': 3, 'name': 'Charlie', 'active': True}100]101102# Extract all names103names→ ['Alice', 'Bob', 'Charlie'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'), users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]))104print(f"Names: {names['Alice', 'Bob', 'Charlie']}")105106# Extract ids of active users107active_ids→ [1, 3] = [108    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('id')(user)109    for user in users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]110    if user['active'](empty)111]112print(f"Active IDs: {active_ids[1, 3]}")113114# Min/max115print("\nMin/max:")116117products→ [{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}] = [118    {'name': 'Widget', 'price': 29.99},119    {'name': 'Gadget', 'price': 49.99},120    {'name': 'Tool', 'price': 19.99}121]122123cheapest→ {'name': 'Tool', 'price': 19.99} = min(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))124print(f"Cheapest: {cheapest{'name': 'Tool', 'price': 19.99}}")125126most_expensive→ {'name': 'Gadget', 'price': 49.99} = max(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))127print(f"Most expensive: {most_expensive{'name': 'Gadget', 'price': 49.99}}")128129# Grouping130print("\nGrouping:")131132from itertools import groupby133134transactions→ [{'category': 'food', 'amount': 50}, {'category': 'transport', 'amount': 20}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 15}] = [135    {'category': 'food', 'amount': 50},136    {'category': 'transport', 'amount': 20},137    {'category': 'food', 'amount': 30},138    {'category': 'transport', 'amount': 15}139]140141# Must sort first for groupby142transactions→ [{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}].sort(key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category'))
    output
    Map and filter:
    Names: ['Alice', 'Bob', 'Charlie']
    Active IDs: [1, 3]
    
    Min/max:
    Cheapest: {'name': 'Tool', 'price': 19.99}
    Most expensive: {'name': 'Gadget', 'price': 49.99}
    
    Grouping:
  12. total ← 80

    pass 1 of 2
    144for categoryfood, items⟨_grouper A⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 80 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper A⟩)147    print(f"{categoryfood}: ${total80}")
    outputfood: $80
  13. total ← 35

    pass 2 of 2
    144for categorytransport, items⟨_grouper B⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 35 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper B⟩)147    print(f"{categorytransport}: ${total35}")
    outputtransport: $35
  1. get_first ← operator.itemgetter(0), numbers ← [100, 200, 300]

    1"""operator.itemgetter examples"""23import operator45# Basic itemgetter6print("Basic itemgetter:")78# Get single item9get_first→ operator.itemgetter(0) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0)10numbers→ [100, 200, 300] = [100, 200, 300]1112print(f"get_first({numbers[100, 200, 300]}): {get_first(numbers)}")1314# Get by key15data→ {'name': 'Alice', 'age': 30} = {'name': 'Alice', 'age': 30}16get_name→ operator.itemgetter('name') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name')17print(f"get_name({data{'name': 'Alice', 'age': 30}}): {get_name(data)}")1819# Multiple items20print("\nMultiple items:")2122# Get multiple indices23get_items→ operator.itemgetter(0, 2, 4) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(0, 2, 4)24letters→ ['a', 'b', 'c', 'd', 'e'] = ['a', 'b', 'c', 'd', 'e']2526result→ ('a', 'c', 'e') = get_items(letters['a', 'b', 'c', 'd', 'e'])27print(f"get_items({letters['a', 'b', 'c', 'd', 'e']}): {result('a', 'c', 'e')}")2829# Multiple keys30get_info→ operator.itemgetter('name', 'age') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name', 'age')31person→ {'name': 'Bob', 'age': 25, 'city': 'NYC'} = {'name': 'Bob', 'age': 25, 'city': 'NYC'}32print(f"get_info: {get_info(person{'name': 'Bob', 'age': 25, 'city': 'NYC'})}")3334# Sorting lists35print("\nSorting lists:")3637students→ [{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}] = [38    {'name': 'Charlie', 'grade': 85},39    {'name': 'Alice', 'grade': 92},40    {'name': 'Bob', 'grade': 78}41]4243# Sort by grade44sorted_by_grade→ [{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('grade'))45print("Sorted by grade:")46for s in sorted_by_grade:
    outputBasic itemgetter:
    get_first([100, 200, 300]): 100
    get_name({'name': 'Alice', 'age': 30}): Alice
    
    Multiple items:
    get_items(['a', 'b', 'c', 'd', 'e']): ('a', 'c', 'e')
    get_info: ('Bob', 25)
    
    Sorting lists:
    Sorted by grade:
  2. for s in sorted_by_grade:

    pass 1 of 3
    45print("Sorted by grade:")46for s{'name': 'Bob', 'grade': 78} in sorted_by_grade[{'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}]:47    print(f"  {s{'name': 'Bob', 'grade': 78}}")
    output  {'name': 'Bob', 'grade': 78}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Bob', 'grade': 78}
    2{'name': 'Charlie', 'grade': 85}
    3{'name': 'Alice', 'grade': 92}
  3. sorted_by_name ← [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]

    49# Sort by name50sorted_by_name→ [{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}] = sorted(students[{'name': 'Charlie', 'grade': 85}, {'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'))51print("\nSorted by name:")52for s in sorted_by_name:
    output
    Sorted by name:
  4. for s in sorted_by_name:

    pass 1 of 3
    51print("\nSorted by name:")52for s{'name': 'Alice', 'grade': 92} in sorted_by_name[{'name': 'Alice', 'grade': 92}, {'name': 'Bob', 'grade': 78}, {'name': 'Charlie', 'grade': 85}]:53    print(f"  {s{'name': 'Alice', 'grade': 92}}")
    output  {'name': 'Alice', 'grade': 92}
    All 3 passes — pass 1 is the card above
    passs
    1{'name': 'Alice', 'grade': 92}
    2{'name': 'Bob', 'grade': 78}
    3{'name': 'Charlie', 'grade': 85}
  5. data ← [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}]

    55# Nested sorting56print("\nNested sorting:")5758data→ [{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}] = [59    {'name': 'Alice', 'scores': [85, 90]},60    {'name': 'Bob', 'scores': [92, 88]},61    {'name': 'Charlie', 'scores': [78, 95]}62]6364# Sort by first score65sorted_data→ [{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}] = sorted(data[{'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}, {'name': 'Charlie', 'scores': [78, 95]}], 66    key=lambda x: operator.itemgetter(0)(x['scores']))6768print("Sorted by first score:")69for d in sorted_data:
    output
    Nested sorting:
    Sorted by first score:
  6. for d in sorted_data:

    pass 1 of 3
    68print("Sorted by first score:")69for d{'name': 'Charlie', 'scores': [78, 95]} in sorted_data[{'name': 'Charlie', 'scores': [78, 95]}, {'name': 'Alice', 'scores': [85, 90]}, {'name': 'Bob', 'scores': [92, 88]}]:70    print(f"  {d{'name': 'Charlie', 'scores': [78, 95]}}")
    output  {'name': 'Charlie', 'scores': [78, 95]}
    All 3 passes — pass 1 is the card above
    passd
    1{'name': 'Charlie', 'scores': [78, 95]}
    2{'name': 'Alice', 'scores': [85, 90]}
    3{'name': 'Bob', 'scores': [92, 88]}
  7. records ← [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')]

    72# With tuples73print("\nWith tuples:")7475records→ [('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')] = [76    ('Alice', 30, 'NYC'),77    ('Bob', 25, 'LA'),78    ('Charlie', 35, 'Chicago')79]8081# Sort by age (index 1)82sorted_by_age→ [('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(1))83print("Sorted by age:")84for r in sorted_by_age:
    output
    With tuples:
    Sorted by age:
  8. for r in sorted_by_age:

    pass 1 of 3
    83print("Sorted by age:")84for r('Bob', 25, 'LA') in sorted_by_age[('Bob', 25, 'LA'), ('Alice', 30, 'NYC'), ('Charlie', 35, 'Chicago')]:85    print(f"  {r('Bob', 25, 'LA')}")
    output  ('Bob', 25, 'LA')
    All 3 passes — pass 1 is the card above
    passr
    1('Bob', 25, 'LA')
    2('Alice', 30, 'NYC')
    3('Charlie', 35, 'Chicago')
  9. sorted_multi ← [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]

    87# Sort by multiple fields (city, then age)88sorted_multi→ [('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')] = sorted(records[('Alice', 30, 'NYC'), ('Bob', 25, 'LA'), ('Charlie', 35, 'Chicago')], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter(2, 1))89print("\nSorted by city then age:")90for r in sorted_multi:
    output
    Sorted by city then age:
  10. for r in sorted_multi:

    pass 1 of 3
    89print("\nSorted by city then age:")90for r('Charlie', 35, 'Chicago') in sorted_multi[('Charlie', 35, 'Chicago'), ('Bob', 25, 'LA'), ('Alice', 30, 'NYC')]:91    print(f"  {r('Charlie', 35, 'Chicago')}")
    output  ('Charlie', 35, 'Chicago')
    All 3 passes — pass 1 is the card above
    passr
    1('Charlie', 35, 'Chicago')
    2('Bob', 25, 'LA')
    3('Alice', 30, 'NYC')
  11. users ← [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]

    93# Map and filter94print("\nMap and filter:")9596users→ [{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}] = [97    {'id': 1, 'name': 'Alice', 'active': True},98    {'id': 2, 'name': 'Bob', 'active': False},99    {'id': 3, 'name': 'Charlie', 'active': True}100]101102# Extract all names103names→ ['Alice', 'Bob', 'Charlie'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('name'), users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]))104print(f"Names: {names['Alice', 'Bob', 'Charlie']}")105106# Extract ids of active users107active_ids→ [1, 3] = [108    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('id')(user)109    for user in users[{'id': 1, 'name': 'Alice', 'active': True}, {'id': 2, 'name': 'Bob', 'active': False}, {'id': 3, 'name': 'Charlie', 'active': True}]110    if user['active'](empty)111]112print(f"Active IDs: {active_ids[1, 3]}")113114# Min/max115print("\nMin/max:")116117products→ [{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}] = [118    {'name': 'Widget', 'price': 29.99},119    {'name': 'Gadget', 'price': 49.99},120    {'name': 'Tool', 'price': 19.99}121]122123cheapest→ {'name': 'Tool', 'price': 19.99} = min(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))124print(f"Cheapest: {cheapest{'name': 'Tool', 'price': 19.99}}")125126most_expensive→ {'name': 'Gadget', 'price': 49.99} = max(products[{'name': 'Widget', 'price': 29.99}, {'name': 'Gadget', 'price': 49.99}, {'name': 'Tool', 'price': 19.99}], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('price'))127print(f"Most expensive: {most_expensive{'name': 'Gadget', 'price': 49.99}}")128129# Grouping130print("\nGrouping:")131132from itertools import groupby133134transactions→ [{'category': 'food', 'amount': 50}, {'category': 'transport', 'amount': 20}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 15}] = [135    {'category': 'food', 'amount': 50},136    {'category': 'transport', 'amount': 20},137    {'category': 'food', 'amount': 30},138    {'category': 'transport', 'amount': 15}139]140141# Must sort first for groupby142transactions→ [{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}].sort(key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category'))
    output
    Map and filter:
    Names: ['Alice', 'Bob', 'Charlie']
    Active IDs: [1, 3]
    
    Min/max:
    Cheapest: {'name': 'Tool', 'price': 19.99}
    Most expensive: {'name': 'Gadget', 'price': 49.99}
    
    Grouping:
  12. total ← 80

    pass 1 of 2
    144for categoryfood, items⟨_grouper A⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 80 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper A⟩)147    print(f"{categoryfood}: ${total80}")
    outputfood: $80
  13. total ← 35

    pass 2 of 2
    144for categorytransport, items⟨_grouper B⟩ in groupby(transactions[{'category': 'food', 'amount': 50}, {'category': 'food', 'amount': 30}, {'category': 'transport', 'amount': 20}, {'category': 'transport', 'amount': 15}], 145                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('category')):146    total→ 35 = sum(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.itemgetter('amount')(item) for item in items⟨_grouper B⟩)147    print(f"{categorytransport}: ${total35}")
    outputtransport: $35
itemgetter Creates a callable that retrieves items by key or index - cleaner and faster than lambda x: x['key'] for sorting and mapping.

Attrgetter

Extract attributes from objects:

attrgetter.py
Replay: real traced execution (multi-file project)
"""operator.attrgetter examples"""

import operator
from datetime import datetime

# Basic attrgetter
print("Basic attrgetter:")

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person('{self.name}', {self.age})"

# Get single attribute
get_name = operator.attrgetter('name')
person = Person('Alice', 30)

print(f"get_name({person}): {get_name(person)}")
print(f"Equivalent to: {person.name}")

# Multiple attributes
print("\nMultiple attributes:")

# Get multiple attributes
get_info = operator.attrgetter('name', 'age')
result = get_info(person)
print(f"get_info: {result}")

# Sorting objects
print("\nSorting objects:")

people = [
    Person('Charlie', 35),
    Person('Alice', 30),
    Person('Bob', 25)
]

# Sort by name
sorted_by_name = sorted(people, key=operator.attrgetter('name'))
print("Sorted by name:")
for p in sorted_by_name:
    print(f"  {p}")

# Sort by age
sorted_by_age = sorted(people, key=operator.attrgetter('age'))
print("\nSorted by age:")
for p in sorted_by_age:
    print(f"  {p}")

# Nested attributes
print("\nNested attributes:")

class Address:
    def __init__(self, city, zip_code):
        self.city = city
        self.zip = zip_code

    def __repr__(self):
        return f"Address('{self.city}', '{self.zip}')"

class Employee:
    def __init__(self, name, address):
        self.name = name
        self.address = address

    def __repr__(self):
        return f"Employee('{self.name}', {self.address})"

employees = [
    Employee('Alice', Address('NYC', '10001')),
    Employee('Bob', Address('LA', '90001')),
    Employee('Charlie', Address('Chicago', '60601'))
]

# Access nested attribute
get_city = operator.attrgetter('address.city')
cities = [get_city(emp) for emp in employees]
print(f"Cities: {cities}")

# Sort by nested attribute
sorted_by_city = sorted(employees, key=operator.attrgetter('address.city'))
print("\nSorted by city:")
for emp in sorted_by_city:
    print(f"  {emp}")

# Min/max
print("\nMin/max:")

class Product:
    def __init__(self, name, price, quantity):
        self.name = name
        self.price = price
        self.quantity = quantity

    def __repr__(self):
        return f"Product('{self.name}', ${self.price}, qty={self.quantity})"

products = [
    Product('Widget', 29.99, 100),
    Product('Gadget', 49.99, 50),
    Product('Tool', 19.99, 200)
]

cheapest = min(products, key=operator.attrgetter('price'))
print(f"Cheapest: {cheapest}")

most_stock = max(products, key=operator.attrgetter('quantity'))
print(f"Most stock: {most_stock}")

# Map operations
print("\nMap operations:")

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

students = [
    Student('Alice', 92),
    Student('Bob', 85),
    Student('Charlie', 78)
]

# Extract all names
names = list(map(operator.attrgetter('name'), students))
print(f"Names: {names}")

# Extract all grades
grades = list(map(operator.attrgetter('grade'), students))
print(f"Grades: {grades}")

# Multiple attributes
info = list(map(operator.attrgetter('name', 'grade'), students))
print(f"Info: {info}")

# Filtering
print("\nFiltering:")

class Task:
    def __init__(self, name, priority, completed):
        self.name = name
        self.priority = priority
        self.completed = completed

    def __repr__(self):
        return f"Task('{self.name}', priority={self.priority}, done={self.completed})"

tasks = [
    Task('Review code', 3, False),
    Task('Fix bug', 1, True),
    Task('Write tests', 2, False)
]

# High priority incomplete tasks
high_priority = [
    t for t in tasks
    if operator.attrgetter('priority')(t) <= 2 and not t.completed
]

print("High priority incomplete:")
for t in high_priority:
    print(f"  {t}")

# Grouping
print("\nGrouping:")

from itertools import groupby

class Record:
    def __init__(self, category, value):
        self.category = category
        self.value = value

records = [
    Record('A', 10),
    Record('B', 20),
    Record('A', 15),
    Record('B', 25),
    Record('A', 5)
]

# Must sort first
records.sort(key=operator.attrgetter('category'))

for category, items in groupby(records,
                               key=operator.attrgetter('category')):
    values = [operator.attrgetter('value')(r) for r in items]
    print(f"{category}: {values}, sum={sum(values)}")

# With datetime
print("\nWith datetime:")

class Event:
    def __init__(self, name, timestamp):
        self.name = name
        self.timestamp = timestamp

    def __repr__(self):
        return f"Event('{self.name}', {self.timestamp})"

events = [
    Event('Login', datetime(2024, 1, 15, 10, 30)),
    Event('Purchase', datetime(2024, 1, 15, 11, 45)),
    Event('Logout', datetime(2024, 1, 15, 9, 15))
]

# Sort chronologically
sorted_events = sorted(events, key=operator.attrgetter('timestamp'))
print("Chronological order:")
for e in sorted_events:
    print(f"  {e}")

  1. get_name ← operator.attrgetter('name')

    1"""operator.attrgetter examples"""23import operator4from datetime import datetime56# Basic attrgetter7print("Basic attrgetter:")89class Person:10    def __init__(self, name, age):11        self.name = name12        self.age = age13    14    def __repr__(self):15        return f"Person('{self.name}', {self.age})"1617# Get single attribute18get_name→ operator.attrgetter('name') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('name')19person = Person('Alice', 30)
    outputBasic attrgetter:
  2. self.name ← Alice, self.age ← 30

    pass 1 of 4
    9class Person:10    def __init__(self(empty), nameAlice, age30):11        self.name→ Alice = nameAlice12        self.age→ 30 = age30
    All 4 passes — pass 1 is the card above
    passnameageself.nameself.age
    1Alice30Alice30
    2Charlie35Charlie35
    3Alice30Alice30
    4Bob25Bob25
  3. person ← Person('Alice', 30), get_info ← operator.attrgetter('name', 'age')

    18get_name = operator.attrgetter('name')19person→ Person('Alice', 30) = Person('Alice', 30)2021print(f"get_name({personPerson('Alice', 30)}): {get_name(person)}")22print(f"Equivalent to: {person.nameAlice}")2324# Multiple attributes25print("\nMultiple attributes:")2627# Get multiple attributes28get_info→ operator.attrgetter('name', 'age') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('name', 'age')29result→ ('Alice', 30) = get_info(personPerson('Alice', 30))30print(f"get_info: {result('Alice', 30)}")3132# Sorting objects33print("\nSorting objects:")3435people = [36    Person('Charlie', 35),37    Person('Alice', 30),38    Person('Bob', 25)39]
    outputget_name(Person('Alice', 30)): Alice
    Equivalent to: Alice
    
    Multiple attributes:
    get_info: ('Alice', 30)
    
    Sorting objects:
  4. people ← [Person('Charlie', 35), Person('Alice', 30), Person('Bob', 25)]

    35people→ [Person('Charlie', 35), Person('Alice', 30), Person('Bob', 25)] = [36    Person('Charlie', 35),37    Person('Alice', 30),38    Person('Bob', 25)39]4041# Sort by name42sorted_by_name→ [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)] = sorted(people[Person('Charlie', 35), Person('Alice', 30), Person('Bob', 25)], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('name'))43print("Sorted by name:")44for p in sorted_by_name:
    outputSorted by name:
  5. for p in sorted_by_name:

    pass 1 of 3
    43print("Sorted by name:")44for pPerson('Alice', 30) in sorted_by_name[Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)]:45    print(f"  {pPerson('Alice', 30)}")
    output  Person('Alice', 30)
    All 3 passes — pass 1 is the card above
    passp
    1Person('Alice', 30)
    2Person('Bob', 25)
    3Person('Charlie', 35)
  6. sorted_by_age ← [Person('Bob', 25), Person('Alice', 30), Person('Charlie', 35)]

    47# Sort by age48sorted_by_age→ [Person('Bob', 25), Person('Alice', 30), Person('Charlie', 35)] = sorted(people[Person('Charlie', 35), Person('Alice', 30), Person('Bob', 25)], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('age'))49print("\nSorted by age:")50for p in sorted_by_age:
    output
    Sorted by age:
  7. for p in sorted_by_age:

    pass 1 of 3
    49print("\nSorted by age:")50for pPerson('Bob', 25) in sorted_by_age[Person('Bob', 25), Person('Alice', 30), Person('Charlie', 35)]:51    print(f"  {pPerson('Bob', 25)}")
    output  Person('Bob', 25)
    All 3 passes — pass 1 is the card above
    passp
    1Person('Bob', 25)
    2Person('Alice', 30)
    3Person('Charlie', 35)
  8. print(" Nested attributes:")

    53# Nested attributes54print("\nNested attributes:")5556class Address:57    def __init__(self, city, zip_code):58        self.city = city59        self.zip = zip_code60    61    def __repr__(self):62        return f"Address('{self.city}', '{self.zip}')"6364class Employee:65    def __init__(self, name, address):66        self.name = name67        self.address = address68    69    def __repr__(self):70        return f"Employee('{self.name}', {self.address})"7172employees = [73    Employee('Alice', Address('NYC', '10001')),74    Employee('Bob', Address('LA', '90001')),75    Employee('Charlie', Address('Chicago', '60601'))76]
    output
    Nested attributes:
  9. self.city ← NYC, self.zip ← 10001

    pass 1 of 3
    56class Address:57    def __init__(self(empty), cityNYC, zip_code10001):58        self.city→ NYC = cityNYC59        self.zip→ 10001 = zip_code10001
    All 3 passes — pass 1 is the card above
    passcityzip_codeself.cityself.zip
    1NYC10001NYC10001
    2LA90001LA90001
    3Chicago60601Chicago60601
  10. self.name ← Alice, self.address ← Address('NYC', '10001')

    pass 1 of 3
    64class Employee:65    def __init__(self(empty), nameAlice, addressAddress('NYC', '10001')):66        self.name→ Alice = nameAlice67        self.address→ Address('NYC', '10001') = addressAddress('NYC', '10001')
    All 3 passes — pass 1 is the card above
    passnameaddressself.nameself.address
    1AliceAddress('NYC', '10001')AliceAddress('NYC', '10001')
    2BobAddress('LA', '90001')BobAddress('LA', '90001')
    3CharlieAddress('Chicago', '60601')CharlieAddress('Chicago', '60601')
  11. employees ← [Employee('Alice', Address('NYC', '10001')), Employee('Bob', Address('LA', '90001')), Employee('Charlie', Address('Chicago', '60601'))]

    72employees→ [Employee('Alice', Address('NYC', '10001')), Employee('Bob', Address('LA', '90001')), Employee('Charlie', Address('Chicago', '60601'))] = [73    Employee('Alice', Address('NYC', '10001')),74    Employee('Bob', Address('LA', '90001')),75    Employee('Charlie', Address('Chicago', '60601'))76]7778# Access nested attribute79get_city→ operator.attrgetter('address.city') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('address.city')80cities→ ['NYC', 'LA', 'Chicago'] = [get_city(emp) for emp in employees[Employee('Alice', Address('NYC', '10001')), Employee('Bob', Address('LA', '90001')), Employee('Charlie', Address('Chicago', '60601'))]]81print(f"Cities: {cities['NYC', 'LA', 'Chicago']}")8283# Sort by nested attribute84sorted_by_city→ [Employee('Charlie', Address('Chicago', '60601')), Employee('Bob', Address('LA', '90001')), Employee('Alice', Address('NYC', '10001'))] = sorted(employees[Employee('Alice', Address('NYC', '10001')), Employee('Bob', Address('LA', '90001')), Employee('Charlie', Address('Chicago', '60601'))], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('address.city'))85print("\nSorted by city:")86for emp in sorted_by_city:
    outputCities: ['NYC', 'LA', 'Chicago']
    
    Sorted by city:
  12. for emp in sorted_by_city:

    pass 1 of 3
    85print("\nSorted by city:")86for empEmployee('Charlie', Address('Chicago', '60601')) in sorted_by_city[Employee('Charlie', Address('Chicago', '60601')), Employee('Bob', Address('LA', '90001')), Employee('Alice', Address('NYC', '10001'))]:87    print(f"  {empEmployee('Charlie', Address('Chicago', '60601'))}")
    output  Employee('Charlie', Address('Chicago', '60601'))
    All 3 passes — pass 1 is the card above
    passemp
    1Employee('Charlie', Address('Chicago', '60601'))
    2Employee('Bob', Address('LA', '90001'))
    3Employee('Alice', Address('NYC', '10001'))
  13. print(" Min/max:")

    89# Min/max90print("\nMin/max:")9192class Product:93    def __init__(self, name, price, quantity):94        self.name = name95        self.price = price96        self.quantity = quantity97    98    def __repr__(self):99        return f"Product('{self.name}', ${self.price}, qty={self.quantity})"100101products = [102    Product('Widget', 29.99, 100),103    Product('Gadget', 49.99, 50),104    Product('Tool', 19.99, 200)105]
    output
    Min/max:
  14. self.name ← Widget, self.price ← 29.99, self.quantity ← 100

    pass 1 of 3
    92class Product:93    def __init__(self(empty), nameWidget, price29.99, quantity100):94        self.name→ Widget = nameWidget95        self.price→ 29.99 = price29.9996        self.quantity→ 100 = quantity100
    All 3 passes — pass 1 is the card above
    passnamepricequantityself.nameself.priceself.quantity
    1Widget29.99100Widget29.99100
    2Gadget49.9950Gadget49.9950
    3Tool19.99200Tool19.99200
  15. products ← [Product('Widget', $29.99, qty=100), Product('Gadget', $49.99, qty=50), Product('Tool', $19.99, qty=200)]

    101products→ [Product('Widget', $29.99, qty=100), Product('Gadget', $49.99, qty=50), Product('Tool', $19.99, qty=200)] = [102    Product('Widget', 29.99, 100),103    Product('Gadget', 49.99, 50),104    Product('Tool', 19.99, 200)105]106107cheapest→ Product('Tool', $19.99, qty=200) = min(products[Product('Widget', $29.99, qty=100), Product('Gadget', $49.99, qty=50), Product('Tool', $19.99, qty=200)], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('price'))108print(f"Cheapest: {cheapestProduct('Tool', $19.99, qty=200)}")109110most_stock→ Product('Tool', $19.99, qty=200) = max(products[Product('Widget', $29.99, qty=100), Product('Gadget', $49.99, qty=50), Product('Tool', $19.99, qty=200)], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('quantity'))111print(f"Most stock: {most_stockProduct('Tool', $19.99, qty=200)}")112113# Map operations114print("\nMap operations:")115116class Student:117    def __init__(self, name, grade):118        self.name = name119        self.grade = grade120121students = [122    Student('Alice', 92),123    Student('Bob', 85),124    Student('Charlie', 78)125]
    outputCheapest: Product('Tool', $19.99, qty=200)
    Most stock: Product('Tool', $19.99, qty=200)
    
    Map operations:
  16. self.name ← Alice, self.grade ← 92

    pass 1 of 3
    116class Student:117    def __init__(self⟨Student A⟩, nameAlice, grade92):118        self.name→ Alice = nameAlice119        self.grade→ 92 = grade92
    All 3 passes — pass 1 is the card above
    passselfnamegradeself.nameself.grade
    1⟨Student A⟩Alice92Alice92
    2⟨Student B⟩Bob85Bob85
    3⟨Student C⟩Charlie78Charlie78
  17. students ← [⟨Student A⟩, ⟨Student B⟩, ⟨Student C⟩], names ← ['Alice', 'Bob', 'Charlie']

    121students→ [⟨Student A⟩, ⟨Student B⟩, ⟨Student C⟩] = [122    Student('Alice', 92),123    Student('Bob', 85),124    Student('Charlie', 78)125]126127# Extract all names128names→ ['Alice', 'Bob', 'Charlie'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('name'), students[⟨Student A⟩, ⟨Student B⟩, ⟨Student C⟩]))129print(f"Names: {names['Alice', 'Bob', 'Charlie']}")130131# Extract all grades132grades→ [92, 85, 78] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('grade'), students[⟨Student A⟩, ⟨Student B⟩, ⟨Student C⟩]))133print(f"Grades: {grades[92, 85, 78]}")134135# Multiple attributes136info→ [('Alice', 92), ('Bob', 85), ('Charlie', 78)] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('name', 'grade'), students[⟨Student A⟩, ⟨Student B⟩, ⟨Student C⟩]))137print(f"Info: {info[('Alice', 92), ('Bob', 85), ('Charlie', 78)]}")138139# Filtering140print("\nFiltering:")141142class Task:143    def __init__(self, name, priority, completed):144        self.name = name145        self.priority = priority146        self.completed = completed147    148    def __repr__(self):149        return f"Task('{self.name}', priority={self.priority}, done={self.completed})"150151tasks = [152    Task('Review code', 3, False),153    Task('Fix bug', 1, True),154    Task('Write tests', 2, False)155]
    outputNames: ['Alice', 'Bob', 'Charlie']
    Grades: [92, 85, 78]
    Info: [('Alice', 92), ('Bob', 85), ('Charlie', 78)]
    
    Filtering:
  18. self.name ← Review code, self.priority ← 3, self.completed ← False

    pass 1 of 3
    142class Task:143    def __init__(self(empty), nameReview code, priority3, completedFalse):144        self.name→ Review code = nameReview code145        self.priority→ 3 = priority3146        self.completed→ False = completedFalse
    All 3 passes — pass 1 is the card above
    passnameprioritycompletedself.nameself.priorityself.completed
    1Review code3FalseReview code3False
    2Fix bug1TrueFix bug1True
    3Write tests2FalseWrite tests2False
  19. tasks ← [Task('Review code', priority=3, done=False), Task('Fix bug', priority=1, done=True), Task('Write tests', priority=2, done=False)]

    151tasks→ [Task('Review code', priority=3, done=False), Task('Fix bug', priority=1, done=True), Task('Write tests', priority=2, done=False)] = [152    Task('Review code', 3, False),153    Task('Fix bug', 1, True),154    Task('Write tests', 2, False)155]156157# High priority incomplete tasks158high_priority→ [Task('Write tests', priority=2, done=False)] = [159    t for t in tasks[Task('Review code', priority=3, done=False), Task('Fix bug', priority=1, done=True), Task('Write tests', priority=2, done=False)]160    if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('priority')(t) <= 2 and not t.completed(empty)161]162163print("High priority incomplete:")164for t in high_priority:
    outputHigh priority incomplete:
  20. for t in high_priority:

    163print("High priority incomplete:")164for tTask('Write tests', priority=2, done=False) in high_priority[Task('Write tests', priority=2, done=False)]:165    print(f"  {tTask('Write tests', priority=2, done=False)}")
    output  Task('Write tests', priority=2, done=False)
  21. print(" Grouping:")

    167# Grouping168print("\nGrouping:")169170from itertools import groupby171172class Record:173    def __init__(self, category, value):174        self.category = category175        self.value = value176177records = [178    Record('A', 10),179    Record('B', 20),180    Record('A', 15),181    Record('B', 25),182    Record('A', 5)183]
    output
    Grouping:
  22. self.category ← A, self.value ← 10

    pass 1 of 5
    172class Record:173    def __init__(self⟨Record D⟩, categoryA, value10):174        self.category→ A = categoryA175        self.value→ 10 = value10
    All 5 passes — pass 1 is the card above
    passselfcategoryvalueself.categoryself.value
    1⟨Record D⟩A10A10
    2⟨Record E⟩B20B20
    3⟨Record F⟩A15A15
    4⟨Record G⟩B25B25
    5⟨Record H⟩A5A5
  23. records ← [⟨Record D⟩, ⟨Record E⟩, ⟨Record F⟩, ⟨Record G⟩, ⟨Record H⟩]

    177records→ [⟨Record D⟩, ⟨Record E⟩, ⟨Record F⟩, ⟨Record G⟩, ⟨Record H⟩] = [178    Record('A', 10),179    Record('B', 20),180    Record('A', 15),181    Record('B', 25),182    Record('A', 5)183]184185# Must sort first186records→ [⟨Record D⟩, ⟨Record F⟩, ⟨Record H⟩, ⟨Record E⟩, ⟨Record G⟩].sort(key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('category'))
  24. values ← [10, 15, 5]

    pass 1 of 2
    188for categoryA, items⟨_grouper I⟩ in groupby(records[⟨Record D⟩, ⟨Record F⟩, ⟨Record H⟩, ⟨Record E⟩, ⟨Record G⟩], 189                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('category')):190    values→ [10, 15, 5] = [operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('value')(r) for r in items⟨_grouper I⟩]191    print(f"{categoryA}: {values[10, 15, 5]}, sum={sum(values)}")
    outputA: [10, 15, 5], sum=30
  25. values ← [20, 25]

    pass 2 of 2
    188for categoryB, items⟨_grouper J⟩ in groupby(records[⟨Record D⟩, ⟨Record F⟩, ⟨Record H⟩, ⟨Record E⟩, ⟨Record G⟩], 189                               key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('category')):190    values→ [20, 25] = [operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('value')(r) for r in items⟨_grouper J⟩]191    print(f"{categoryB}: {values[20, 25]}, sum={sum(values)}")
    outputB: [20, 25], sum=45
  26. print(" With datetime:")

    193# With datetime194print("\nWith datetime:")195196class Event:197    def __init__(self, name, timestamp):198        self.name = name199        self.timestamp = timestamp200    201    def __repr__(self):202        return f"Event('{self.name}', {self.timestamp})"203204events = [205    Event('Login', datetime(2024, 1, 15, 10, 30)),206    Event('Purchase', datetime(2024, 1, 15, 11, 45)),207    Event('Logout', datetime(2024, 1, 15, 9, 15))208]
    output
    With datetime:
  27. self.name ← Login, self.timestamp ← 2024-01-15 10:30:00

    pass 1 of 3
    196class Event:197    def __init__(self(empty), nameLogin, timestamp2024-01-15 10:30:00):198        self.name→ Login = nameLogin199        self.timestamp→ 2024-01-15 10:30:00 = timestamp2024-01-15 10:30:00
    All 3 passes — pass 1 is the card above
    passnametimestampself.nameself.timestamp
    1Login2024-01-15 10:30:00Login2024-01-15 10:30:00
    2Purchase2024-01-15 11:45:00Purchase2024-01-15 11:45:00
    3Logout2024-01-15 09:15:00Logout2024-01-15 09:15:00
  28. events ← [Event('Login', 2024-01-15 10:30:00), Event('Purchase', 2024-01-15 11:45:00), Event('Logout', 2024-01-15 09:15:00)]

    204events→ [Event('Login', 2024-01-15 10:30:00), Event('Purchase', 2024-01-15 11:45:00), Event('Logout', 2024-01-15 09:15:00)] = [205    Event('Login', datetime(2024, 1, 15, 10, 30)),206    Event('Purchase', datetime(2024, 1, 15, 11, 45)),207    Event('Logout', datetime(2024, 1, 15, 9, 15))208]209210# Sort chronologically211sorted_events→ [Event('Logout', 2024-01-15 09:15:00), Event('Login', 2024-01-15 10:30:00), Event('Purchase', 2024-01-15 11:45:00)] = sorted(events[Event('Login', 2024-01-15 10:30:00), Event('Purchase', 2024-01-15 11:45:00), Event('Logout', 2024-01-15 09:15:00)], key=operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.attrgetter('timestamp'))212print("Chronological order:")213for e in sorted_events:
    outputChronological order:
  29. for e in sorted_events:

    pass 1 of 3
    212print("Chronological order:")213for eEvent('Logout', 2024-01-15 09:15:00) in sorted_events[Event('Logout', 2024-01-15 09:15:00), Event('Login', 2024-01-15 10:30:00), Event('Purchase', 2024-01-15 11:45:00)]:214    print(f"  {eEvent('Logout', 2024-01-15 09:15:00)}")
    output  Event('Logout', 2024-01-15 09:15:00)
    All 3 passes — pass 1 is the card above
    passe
    1Event('Logout', 2024-01-15 09:15:00)
    2Event('Login', 2024-01-15 10:30:00)
    3Event('Purchase', 2024-01-15 11:45:00)
attrgetter Creates a callable that retrieves object attributes - supports nested attributes like 'address.city' and multiple attributes.

Methodcaller

Call methods on objects:

methodcaller.py
Replay: real traced execution (multi-file project)
"""operator.methodcaller examples"""

import operator

# Basic methodcaller
print("Basic methodcaller:")

# Call method with no arguments
upper = operator.methodcaller('upper')
text = "hello"

print(f"upper('{text}'): {upper(text)}")
print(f"Equivalent to: {text.upper()}")

# Call with arguments
replace_o = operator.methodcaller('replace', 'o', 'x')
result = replace_o("hello world")
print(f"replace_o('hello world'): {result}")

# String methods
print("\nString methods:")

strings = ['hello', 'WORLD', 'Python']

# Map upper
upper_strings = list(map(operator.methodcaller('upper'), strings))
print(f"Upper: {upper_strings}")

# Map lower
lower_strings = list(map(operator.methodcaller('lower'), strings))
print(f"Lower: {lower_strings}")

# Map strip
padded = ['  hello  ', '  world  ', '  python  ']
stripped = list(map(operator.methodcaller('strip'), padded))
print(f"Stripped: {stripped}")

# With arguments
print("\nWith arguments:")

# Replace method
texts = ['hello world', 'foo bar', 'baz qux']
replaced = list(map(operator.methodcaller('replace', 'o', 'X'), texts))
print(f"Replace 'o' with 'X': {replaced}")

# Split method
split_lines = list(map(operator.methodcaller('split', ','),
                      ['a,b,c', 'd,e,f', 'g,h,i']))
print(f"Split by comma: {split_lines}")

# Startswith
check_start = operator.methodcaller('startswith', 'hel')
words = ['hello', 'help', 'world', 'helper']
results = [check_start(w) for w in words]
print(f"Startswith 'hel': {list(zip(words, results))}")

# Custom objects
print("\nCustom objects:")

class Counter:
    def __init__(self, value=0):
        self.value = value

    def increment(self, amount=1):
        self.value += amount
        return self.value

    def reset(self):
        self.value = 0
        return self.value

    def __repr__(self):
        return f"Counter({self.value})"

counters = [Counter(10), Counter(20), Counter(30)]

# Call reset on all
reset_all = operator.methodcaller('reset')
for c in counters:
    reset_all(c)

print(f"After reset: {counters}")

# Increment all by 5
increment_5 = operator.methodcaller('increment', 5)
for c in counters:
    increment_5(c)

print(f"After increment(5): {counters}")

# List methods
print("\nList methods:")

lists = [[3, 1, 2], [6, 4, 5], [9, 7, 8]]

# Sort each list
sort_list = operator.methodcaller('sort')
for lst in lists:
    sort_list(lst)

print(f"After sort: {lists}")

# Append to each
append_10 = operator.methodcaller('append', 10)
for lst in lists:
    append_10(lst)

print(f"After append(10): {lists}")

# Dict methods
print("\nDict methods:")

dicts = [
    {'a': 1, 'b': 2},
    {'c': 3, 'd': 4},
    {'e': 5, 'f': 6}
]

# Get keys from all dicts
get_keys = operator.methodcaller('keys')
all_keys = [list(get_keys(d)) for d in dicts]
print(f"All keys: {all_keys}")

# Get values from all dicts
get_values = operator.methodcaller('values')
all_values = [list(get_values(d)) for d in dicts]
print(f"All values: {all_values}")

# Filtering
print("\nFiltering:")

class Task:
    def __init__(self, name, priority):
        self.name = name
        self.priority = priority

    def is_high_priority(self):
        return self.priority <= 2

    def __repr__(self):
        return f"Task('{self.name}', {self.priority})"

tasks = [
    Task('Fix bug', 1),
    Task('Write docs', 3),
    Task('Review code', 2),
    Task('Update tests', 4)
]

# Filter using method
is_high = operator.methodcaller('is_high_priority')
high_priority = [t for t in tasks if is_high(t)]

print("High priority tasks:")
for t in high_priority:
    print(f"  {t}")

# Chaining operations
print("\nChaining operations:")

class Text:
    def __init__(self, value):
        self.value = value

    def upper(self):
        return Text(self.value.upper())

    def reverse(self):
        return Text(self.value[::-1])

    def strip(self):
        return Text(self.value.strip())

    def __repr__(self):
        return f"Text('{self.value}')"

text = Text('  hello  ')

# Apply operations
operations = [
    operator.methodcaller('strip'),
    operator.methodcaller('upper'),
    operator.methodcaller('reverse')
]

result = text
for op in operations:
    result = op(result)

print(f"Original: {text}")
print(f"After operations: {result}")

# With kwargs
print("\nWith kwargs:")

# Split with keyword arguments
split_max = operator.methodcaller('split', ',', maxsplit=2)
result = split_max('a,b,c,d,e')
print(f"Split with maxsplit=2: {result}")

# Format with kwargs
data = {'name': 'Alice', 'age': 30}
format_str = operator.methodcaller('format', **data)
template = "Name: {name}, Age: {age}"
result = format_str(template)
print(f"Formatted: {result}")

  1. upper ← operator.methodcaller('upper'), text ← hello, replace_o ← operator.methodcaller('replace', 'o', 'x')

    1"""operator.methodcaller examples"""23import operator45# Basic methodcaller6print("Basic methodcaller:")78# Call method with no arguments9upper→ operator.methodcaller('upper') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('upper')10text→ hello = "hello"1112print(f"upper('{texthello}'): {upper(text)}")13print(f"Equivalent to: {texthello.upper()}")1415# Call with arguments16replace_o→ operator.methodcaller('replace', 'o', 'x') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('replace', 'o', 'x')17result→ hellx wxrld = replace_o("hello world")18print(f"replace_o('hello world'): {resulthellx wxrld}")1920# String methods21print("\nString methods:")2223strings→ ['hello', 'WORLD', 'Python'] = ['hello', 'WORLD', 'Python']2425# Map upper26upper_strings→ ['HELLO', 'WORLD', 'PYTHON'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('upper'), strings['hello', 'WORLD', 'Python']))27print(f"Upper: {upper_strings['HELLO', 'WORLD', 'PYTHON']}")2829# Map lower30lower_strings→ ['hello', 'world', 'python'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('lower'), strings['hello', 'WORLD', 'Python']))31print(f"Lower: {lower_strings['hello', 'world', 'python']}")3233# Map strip34padded→ ['  hello  ', '  world  ', '  python  '] = ['  hello  ', '  world  ', '  python  ']35stripped→ ['hello', 'world', 'python'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('strip'), padded['  hello  ', '  world  ', '  python  ']))36print(f"Stripped: {stripped['hello', 'world', 'python']}")3738# With arguments39print("\nWith arguments:")4041# Replace method42texts→ ['hello world', 'foo bar', 'baz qux'] = ['hello world', 'foo bar', 'baz qux']43replaced→ ['hellX wXrld', 'fXX bar', 'baz qux'] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('replace', 'o', 'X'), texts['hello world', 'foo bar', 'baz qux']))44print(f"Replace 'o' with 'X': {replaced['hellX wXrld', 'fXX bar', 'baz qux']}")4546# Split method47split_lines→ [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']] = list(map(operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('split', ','), 48                      ['a,b,c', 'd,e,f', 'g,h,i']))49print(f"Split by comma: {split_lines[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]}")5051# Startswith52check_start→ operator.methodcaller('startswith', 'hel') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('startswith', 'hel')53words→ ['hello', 'help', 'world', 'helper'] = ['hello', 'help', 'world', 'helper']54results→ [True, True, False, True] = [check_start(w) for w in words['hello', 'help', 'world', 'helper']]55print(f"Startswith 'hel': {list(zip(words['hello', 'help', 'world', 'helper'], results[True, True, False, True]))}")5657# Custom objects58print("\nCustom objects:")5960class Counter:61    def __init__(self, value=0):62        self.value = value63    64    def increment(self, amount=1):65        self.value += amount66        return self.value67    68    def reset(self):69        self.value = 070        return self.value71    72    def __repr__(self):73        return f"Counter({self.value})"7475counters = [Counter(10), Counter(20), Counter(30)]
    outputBasic methodcaller:
    upper('hello'): HELLO
    Equivalent to: HELLO
    replace_o('hello world'): hellx wxrld
    
    String methods:
    Upper: ['HELLO', 'WORLD', 'PYTHON']
    Lower: ['hello', 'world', 'python']
    Stripped: ['hello', 'world', 'python']
    
    With arguments:
    Replace 'o' with 'X': ['hellX wXrld', 'fXX bar', 'baz qux']
    Split by comma: [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
    Startswith 'hel': [('hello', True), ('help', True), ('world', False), ('helper', True)]
    
    Custom objects:
  2. self.value ← 10

    pass 1 of 3
    60class Counter:61    def __init__(self(empty), value10=0):62        self.value→ 10 = value10
    All 3 passes — pass 1 is the card above
    passvalueself.value
    11010
    22020
    33030
  3. counters ← [Counter(10), Counter(20), Counter(30)], reset_all ← operator.methodcaller('reset')

    75counters→ [Counter(10), Counter(20), Counter(30)] = [Counter(10), Counter(20), Counter(30)]7677# Call reset on all78reset_all→ operator.methodcaller('reset') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('reset')79for c in counters:
  4. for c in counters:

    pass 1 of 3
    78reset_all = operator.methodcaller('reset')79for cCounter(10) in counters[Counter(10), Counter(20), Counter(30)]:80    reset_all(cCounter(10))
    All 3 passes — pass 1 is the card above
    passccounters
    1Counter(10)[Counter(10), Counter(20), Counter(30)]
    2Counter(20)[Counter(0), Counter(20), Counter(30)]
    3Counter(30)[Counter(0), Counter(0), Counter(30)]
  5. self.value ← 0

    pass 1 of 3
    68def reset(selfCounter(10)):69    self.value→ 0 = 070    return self.value0
    All 3 passes — pass 1 is the card above
    passselfself.value
    1Counter(10)0
    2Counter(20)0
    3Counter(30)0
  6. c ← Counter(0)

    79for c in counters:80    reset_all(c→ Counter(0))
  7. c ← Counter(0)

    79for c in counters:80    reset_all(c→ Counter(0))
  8. c ← Counter(0)

    79for c in counters:80    reset_all(c→ Counter(0))
  9. increment_5 ← operator.methodcaller('increment', 5)

    82print(f"After reset: {counters[Counter(0), Counter(0), Counter(0)]}")8384# Increment all by 585increment_5→ operator.methodcaller('increment', 5) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('increment', 5)86for c in counters:
    outputAfter reset: [Counter(0), Counter(0), Counter(0)]
  10. for c in counters:

    pass 1 of 3
    85increment_5 = operator.methodcaller('increment', 5)86for cCounter(0) in counters[Counter(0), Counter(0), Counter(0)]:87    increment_5(cCounter(0))
    All 3 passes — pass 1 is the card above
    passcounters
    1[Counter(0), Counter(0), Counter(0)]
    2[Counter(5), Counter(0), Counter(0)]
    3[Counter(5), Counter(5), Counter(0)]
  11. self.value ← 5

    pass 1 of 3
    64def increment(selfCounter(0), amount5=1):65    self.value→ 5 += amount566    return self.value5
    All 3 passes — pass 1 is the card above
    passself.value
    10 5
    20 5
    30 5
  12. c ← Counter(5)

    86for c in counters:87    increment_5(c→ Counter(5))
  13. c ← Counter(5)

    86for c in counters:87    increment_5(c→ Counter(5))
  14. c ← Counter(5)

    86for c in counters:87    increment_5(c→ Counter(5))
  15. lists ← [[3, 1, 2], [6, 4, 5], [9, 7, 8]], sort_list ← operator.methodcaller('sort')

    89print(f"After increment(5): {counters[Counter(5), Counter(5), Counter(5)]}")9091# List methods92print("\nList methods:")9394lists→ [[3, 1, 2], [6, 4, 5], [9, 7, 8]] = [[3, 1, 2], [6, 4, 5], [9, 7, 8]]9596# Sort each list97sort_list→ operator.methodcaller('sort') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('sort')98for lst in lists:
    outputAfter increment(5): [Counter(5), Counter(5), Counter(5)]
    
    List methods:
  16. lst ← [1, 2, 3]

    pass 1 of 3
    97sort_list = operator.methodcaller('sort')98for lst[3, 1, 2] in lists[[3, 1, 2], [6, 4, 5], [9, 7, 8]]:99    sort_list(lst→ [1, 2, 3])
    All 3 passes — pass 1 is the card above
    passlistslst
    1[[3, 1, 2], [6, 4, 5], [9, 7, 8]][3, 1, 2] [1, 2, 3]
    2[[1, 2, 3], [6, 4, 5], [9, 7, 8]][6, 4, 5] [4, 5, 6]
    3[[1, 2, 3], [4, 5, 6], [9, 7, 8]][9, 7, 8] [7, 8, 9]
  17. append_10 ← operator.methodcaller('append', 10)

    101print(f"After sort: {lists[[1, 2, 3], [4, 5, 6], [7, 8, 9]]}")102103# Append to each104append_10→ operator.methodcaller('append', 10) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('append', 10)105for lst in lists:
    outputAfter sort: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  18. lst ← [1, 2, 3, 10]

    pass 1 of 3
    104append_10 = operator.methodcaller('append', 10)105for lst[1, 2, 3] in lists[[1, 2, 3], [4, 5, 6], [7, 8, 9]]:106    append_10(lst→ [1, 2, 3, 10])
    All 3 passes — pass 1 is the card above
    passlistslst
    1[[1, 2, 3], [4, 5, 6], [7, 8, 9]][1, 2, 3] [1, 2, 3, 10]
    2[[1, 2, 3, 10], [4, 5, 6], [7, 8, 9]][4, 5, 6] [4, 5, 6, 10]
    3[[1, 2, 3, 10], [4, 5, 6, 10], [7, 8, 9]][7, 8, 9] [7, 8, 9, 10]
  19. dicts ← [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]

    108print(f"After append(10): {lists[[1, 2, 3, 10], [4, 5, 6, 10], [7, 8, 9, 10]]}")109110# Dict methods111print("\nDict methods:")112113dicts→ [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}] = [114    {'a': 1, 'b': 2},115    {'c': 3, 'd': 4},116    {'e': 5, 'f': 6}117]118119# Get keys from all dicts120get_keys→ operator.methodcaller('keys') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('keys')121all_keys→ [['a', 'b'], ['c', 'd'], ['e', 'f']] = [list(get_keys(d)) for d in dicts[{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]]122print(f"All keys: {all_keys[['a', 'b'], ['c', 'd'], ['e', 'f']]}")123124# Get values from all dicts125get_values→ operator.methodcaller('values') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('values')126all_values→ [[1, 2], [3, 4], [5, 6]] = [list(get_values(d)) for d in dicts[{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]]127print(f"All values: {all_values[[1, 2], [3, 4], [5, 6]]}")128129# Filtering130print("\nFiltering:")131132class Task:133    def __init__(self, name, priority):134        self.name = name135        self.priority = priority136    137    def is_high_priority(self):138        return self.priority <= 2139    140    def __repr__(self):141        return f"Task('{self.name}', {self.priority})"142143tasks = [144    Task('Fix bug', 1),145    Task('Write docs', 3),146    Task('Review code', 2),147    Task('Update tests', 4)148]
    outputAfter append(10): [[1, 2, 3, 10], [4, 5, 6, 10], [7, 8, 9, 10]]
    
    Dict methods:
    All keys: [['a', 'b'], ['c', 'd'], ['e', 'f']]
    All values: [[1, 2], [3, 4], [5, 6]]
    
    Filtering:
  20. self.name ← Fix bug, self.priority ← 1

    pass 1 of 4
    132class Task:133    def __init__(self(empty), nameFix bug, priority1):134        self.name→ Fix bug = nameFix bug135        self.priority→ 1 = priority1
    All 4 passes — pass 1 is the card above
    passnamepriorityself.nameself.priority
    1Fix bug1Fix bug1
    2Write docs3Write docs3
    3Review code2Review code2
    4Update tests4Update tests4
  21. tasks ← [Task('Fix bug', 1), Task('Write docs', 3), Task('Review code', 2), Task('Update tests', 4)]

    143tasks→ [Task('Fix bug', 1), Task('Write docs', 3), Task('Review code', 2), Task('Update tests', 4)] = [144    Task('Fix bug', 1),145    Task('Write docs', 3),146    Task('Review code', 2),147    Task('Update tests', 4)148]149150# Filter using method151is_high→ operator.methodcaller('is_high_priority') = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('is_high_priority')152high_priority = [t for t in tasks[Task('Fix bug', 1), Task('Write docs', 3), Task('Review code', 2), Task('Update tests', 4)] if is_high(t)]
  22. def is_high_priority(self):

    pass 1 of 4
    137def is_high_priority(selfTask('Fix bug', 1)):138    return self.priority1 <= 2
    All 4 passes — pass 1 is the card above
    passselfself.priority
    1Task('Fix bug', 1)1
    2Task('Write docs', 3)3
    3Task('Review code', 2)2
    4Task('Update tests', 4)4
  23. high_priority ← [Task('Fix bug', 1), Task('Review code', 2)]

    151is_high = operator.methodcaller('is_high_priority')152high_priority→ [Task('Fix bug', 1), Task('Review code', 2)] = [t for t in tasks[Task('Fix bug', 1), Task('Write docs', 3), Task('Review code', 2), Task('Update tests', 4)] if is_high(t)]153154print("High priority tasks:")155for t in high_priority:
    outputHigh priority tasks:
  24. for t in high_priority:

    pass 1 of 2
    154print("High priority tasks:")155for tTask('Fix bug', 1) in high_priority[Task('Fix bug', 1), Task('Review code', 2)]:156    print(f"  {tTask('Fix bug', 1)}")
    output  Task('Fix bug', 1)
  25. for t in high_priority:

    pass 2 of 2
    154print("High priority tasks:")155for tTask('Review code', 2) in high_priority[Task('Fix bug', 1), Task('Review code', 2)]:156    print(f"  {tTask('Review code', 2)}")
    output  Task('Review code', 2)
  26. print(" Chaining operations:")

    158# Chaining operations159print("\nChaining operations:")160161class Text:162    def __init__(self, value):163        self.value = value164    165    def upper(self):166        return Text(self.value.upper())167    168    def reverse(self):169        return Text(self.value[::-1])170    171    def strip(self):172        return Text(self.value.strip())173    174    def __repr__(self):175        return f"Text('{self.value}')"176177text = Text('  hello  ')
    output
    Chaining operations:
  27. self.value ← hello

    pass 1 of 4
    161class Text:162    def __init__(self(empty), value  hello  ):163        self.value→   hello   = value  hello  
    All 4 passes — pass 1 is the card above
    passvalueself.value
    1 hello hello
    2hellohello
    3HELLOHELLO
    4OLLEHOLLEH
  28. text ← Text(' hello '), operations ← [operator.methodcaller('strip'), operator.methodcaller('upper'), operator.methodcaller('reverse')]

    177text→ Text('  hello  ') = Text('  hello  ')178179# Apply operations180operations→ [operator.methodcaller('strip'), operator.methodcaller('upper'), operator.methodcaller('reverse')] = [181    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('strip'),182    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('upper'),183    operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('reverse')184]185186result→ Text('  hello  ') = textText('  hello  ')187for op in operations:
  29. for op in operations:

    pass 1 of 3
    186result = text187for opoperator.methodcaller('strip') in operations[operator.methodcaller('strip'), operator.methodcaller('upper'), operator.methodcaller('reverse')]:188    result = op(resultText('  hello  '))
    All 3 passes — pass 1 is the card above
    passopresultselfself.valueself.value[::-1]
    1operator.methodcaller('strip')Text(' hello ')Text(' hello ') hello
    2operator.methodcaller('upper')Text('hello')Text('hello')hello
    3operator.methodcaller('reverse')Text('HELLO')Text('HELLO')OLLEH
  30. def strip(self):

    171def strip(selfText('  hello  ')):172    return Text(self.value  hello  .strip())
  31. result ← Text('hello')

    187for op in operations:188    result→ Text('hello') = op(result)
  32. def upper(self):

    165def upper(selfText('hello')):166    return Text(self.valuehello.upper())
  33. result ← Text('HELLO')

    187for op in operations:188    result→ Text('HELLO') = op(result)
  34. def reverse(self):

    168def reverse(selfText('HELLO')):169    return Text(self.value[::-1]OLLEH)
  35. result ← Text('OLLEH')

    187for op in operations:188    result→ Text('OLLEH') = op(result)
  36. split_max ← operator.methodcaller('split', ',', maxsplit=2), result ← ['a', 'b', 'c,d,e']

    190print(f"Original: {textText('  hello  ')}")191print(f"After operations: {resultText('OLLEH')}")192193# With kwargs194print("\nWith kwargs:")195196# Split with keyword arguments197split_max→ operator.methodcaller('split', ',', maxsplit=2) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('split', ',', maxsplit=2)198result→ ['a', 'b', 'c,d,e'] = split_max('a,b,c,d,e')199print(f"Split with maxsplit=2: {result['a', 'b', 'c,d,e']}")200201# Format with kwargs202data→ {'name': 'Alice', 'age': 30} = {'name': 'Alice', 'age': 30}203format_str→ operator.methodcaller('format', name='Alice', age=30) = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.methodcaller('format', **data{'name': 'Alice', 'age': 30})204template→ Name: {name}, Age: {age} = "Name: {name}, Age: {age}"205result→ Name: Alice, Age: 30 = format_str(templateName: {name}, Age: {age})206print(f"Formatted: {resultName: Alice, Age: 30}")
    outputOriginal: Text('  hello  ')
    After operations: Text('OLLEH')
    
    With kwargs:
    Split with maxsplit=2: ['a', 'b', 'c,d,e']
    Formatted: Name: Alice, Age: 30
methodcaller Creates a callable that invokes a named method with optional arguments - useful for applying the same method across many objects.

Arithmetic Operations

Function versions of math operators:

arithmetic.py
Replay: real traced execution (multi-file project)
"""Arithmetic operator functions"""

import operator
from functools import reduce

# Basic arithmetic
print("Basic arithmetic:")

# Addition
print(f"add(5, 3): {operator.add(5, 3)}")
print(f"5 + 3: {5 + 3}")

# Subtraction
print(f"sub(10, 4): {operator.sub(10, 4)}")

# Multiplication
print(f"mul(6, 7): {operator.mul(6, 7)}")

# Division
print(f"truediv(15, 4): {operator.truediv(15, 4)}")
print(f"floordiv(15, 4): {operator.floordiv(15, 4)}")

# Modulo
print(f"mod(17, 5): {operator.mod(17, 5)}")

# Power
print(f"pow(2, 8): {operator.pow(2, 8)}")

# With reduce
print("\nWith reduce:")

numbers = [1, 2, 3, 4, 5]

# Sum using add
total = reduce(operator.add, numbers)
print(f"Sum: {total}")

# Product using mul
product = reduce(operator.mul, numbers)
print(f"Product: {product}")

# Factorial
n = 5
factorial = reduce(operator.mul, range(1, n + 1))
print(f"{n}! = {factorial}")

# Unary operations
print("\nUnary operations:")

# Negation
print(f"neg(5): {operator.neg(5)}")
print(f"neg(-3): {operator.neg(-3)}")

# Positive
print(f"pos(5): {operator.pos(5)}")
print(f"pos(-5): {operator.pos(-5)}")

# Absolute value
print(f"abs(-10): {operator.abs(-10)}")
print(f"abs(7): {operator.abs(7)}")

# String operations
print("\nString operations:")

# String concatenation
result = operator.add("Hello", " World")
print(f"add('Hello', ' World'): {result}")

# String repetition
result = operator.mul("Hi", 3)
print(f"mul('Hi', 3): {result}")

# Join strings with reduce
words = ['Python', 'is', 'awesome']
sentence = reduce(lambda a, b: operator.add(operator.add(a, ' '), b), words)
print(f"Joined: {sentence}")

# List operations
print("\nList operations:")

# List concatenation
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = operator.add(list1, list2)
print(f"add([1,2,3], [4,5,6]): {combined}")

# List repetition
repeated = operator.mul([1, 2], 3)
print(f"mul([1,2], 3): {repeated}")

# Concatenate multiple lists
lists = [[1, 2], [3, 4], [5, 6]]
flattened = reduce(operator.add, lists)
print(f"Flattened: {flattened}")

# Map operations
print("\nMap operations:")

numbers = [1, 2, 3, 4, 5]

# Double all numbers
doubled = list(map(lambda x: operator.mul(x, 2), numbers))
print(f"Doubled: {doubled}")

# Square all numbers
squared = list(map(lambda x: operator.pow(x, 2), numbers))
print(f"Squared: {squared}")

# Negate all numbers
negated = list(map(operator.neg, numbers))
print(f"Negated: {negated}")

# Calculator functions
print("\nCalculator functions:")

def calculate(a, b, op):
    """Apply operator to two numbers"""
    return op(a, b)

print(f"calculate(10, 5, add): {calculate(10, 5, operator.add)}")
print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub)}")
print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul)}")
print(f"calculate(10, 5, truediv): {calculate(10, 5, operator.truediv)}")

# Operation dispatch
print("\nOperation dispatch:")

operations = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.truediv,
    '%': operator.mod,
    '**': operator.pow
}

def eval_expr(a, op, b):
    """Evaluate simple expression"""
    return operations[op](a, b)

print(f"10 + 5 = {eval_expr(10, '+', 5)}")
print(f"10 - 5 = {eval_expr(10, '-', 5)}")
print(f"10 * 5 = {eval_expr(10, '*', 5)}")
print(f"10 / 5 = {eval_expr(10, '/', 5)}")
print(f"10 % 3 = {eval_expr(10, '%', 3)}")
print(f"2 ** 8 = {eval_expr(2, '**', 8)}")

# Cumulative operations
print("\nCumulative operations:")

values = [10, -5, 3, -2, 8]

# Cumulative sum
running_sum = []
total = 0
for v in values:
    total = operator.add(total, v)
    running_sum.append(total)
print(f"Values: {values}")
print(f"Running sum: {running_sum}")

# Cumulative product
running_product = []
product = 1
for v in values:
    product = operator.mul(product, v)
    running_product.append(product)
print(f"Running product: {running_product}")

# In-place operations
print("\nIn-place operations:")

# iadd (+=)
a = 10
a = operator.iadd(a, 5)
print(f"After iadd(10, 5): {a}")

# imul (*=)
b = 3
b = operator.imul(b, 4)
print(f"After imul(3, 4): {b}")

# List iadd
lst = [1, 2, 3]
lst = operator.iadd(lst, [4, 5])
print(f"List after iadd: {lst}")

  1. numbers ← [1, 2, 3, 4, 5], total ← 15, product ← 120, n ← 5, factorial ← 120

    1"""Arithmetic operator functions"""23import operator4from functools import reduce56# Basic arithmetic7print("Basic arithmetic:")89# Addition10print(f"add(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.add(5, 3)}")11print(f"5 + 3: {5 + 3}")1213# Subtraction14print(f"sub(10, 4): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.sub(10, 4)}")1516# Multiplication17print(f"mul(6, 7): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.mul(6, 7)}")1819# Division20print(f"truediv(15, 4): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truediv(15, 4)}")21print(f"floordiv(15, 4): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.floordiv(15, 4)}")2223# Modulo24print(f"mod(17, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.mod(17, 5)}")2526# Power27print(f"pow(2, 8): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.pow(2, 8)}")2829# With reduce30print("\nWith reduce:")3132numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]3334# Sum using add35total→ 15 = reduce(operator.add<built-in function add>, numbers[1, 2, 3, 4, 5])36print(f"Sum: {total15}")3738# Product using mul39product→ 120 = reduce(operator.mul<built-in function mul>, numbers[1, 2, 3, 4, 5])40print(f"Product: {product120}")4142# Factorial43n→ 5 = 544factorial→ 120 = reduce(operator.mul<built-in function mul>, range(1, n5 + 1))45print(f"{n5}! = {factorial120}")4647# Unary operations48print("\nUnary operations:")4950# Negation51print(f"neg(5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.neg(5)}")52print(f"neg(-3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.neg(-3)}")5354# Positive55print(f"pos(5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.pos(5)}")56print(f"pos(-5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.pos(-5)}")5758# Absolute value59print(f"abs(-10): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.abs(-10)}")60print(f"abs(7): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.abs(7)}")6162# String operations63print("\nString operations:")6465# String concatenation66result→ Hello World = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.add("Hello", " World")67print(f"add('Hello', ' World'): {resultHello World}")6869# String repetition70result→ HiHiHi = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.mul("Hi", 3)71print(f"mul('Hi', 3): {resultHiHiHi}")7273# Join strings with reduce74words→ ['Python', 'is', 'awesome'] = ['Python', 'is', 'awesome']75sentence→ Python is awesome = reduce(lambda a, b: operator.add(operator.add(a, ' '), b), words['Python', 'is', 'awesome'])76print(f"Joined: {sentencePython is awesome}")7778# List operations79print("\nList operations:")8081# List concatenation82list1→ [1, 2, 3] = [1, 2, 3]83list2→ [4, 5, 6] = [4, 5, 6]84combined→ [1, 2, 3, 4, 5, 6] = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.add(list1[1, 2, 3], list2[4, 5, 6])85print(f"add([1,2,3], [4,5,6]): {combined[1, 2, 3, 4, 5, 6]}")8687# List repetition88repeated→ [1, 2, 1, 2, 1, 2] = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.mul([1, 2], 3)89print(f"mul([1,2], 3): {repeated[1, 2, 1, 2, 1, 2]}")9091# Concatenate multiple lists92lists→ [[1, 2], [3, 4], [5, 6]] = [[1, 2], [3, 4], [5, 6]]93flattened→ [1, 2, 3, 4, 5, 6] = reduce(operator.add<built-in function add>, lists[[1, 2], [3, 4], [5, 6]])94print(f"Flattened: {flattened[1, 2, 3, 4, 5, 6]}")9596# Map operations97print("\nMap operations:")9899numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]100101# Double all numbers102doubled→ [2, 4, 6, 8, 10] = list(map(lambda x: operator.mul(x, 2), numbers[1, 2, 3, 4, 5]))103print(f"Doubled: {doubled[2, 4, 6, 8, 10]}")104105# Square all numbers106squared→ [1, 4, 9, 16, 25] = list(map(lambda x: operator.pow(x, 2), numbers[1, 2, 3, 4, 5]))107print(f"Squared: {squared[1, 4, 9, 16, 25]}")108109# Negate all numbers110negated→ [-1, -2, -3, -4, -5] = list(map(operator.neg<built-in function neg>, numbers[1, 2, 3, 4, 5]))111print(f"Negated: {negated[-1, -2, -3, -4, -5]}")112113# Calculator functions114print("\nCalculator functions:")115116def calculate(a, b, op):117    """Apply operator to two numbers"""118    return op(a, b)119120print(f"calculate(10, 5, add): {calculate(10, 5, operator.add<built-in function add>)}")121print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub)}")
    outputBasic arithmetic:
    add(5, 3): 8
    5 + 3: 8
    sub(10, 4): 6
    mul(6, 7): 42
    truediv(15, 4): 3.75
    floordiv(15, 4): 3
    mod(17, 5): 2
    pow(2, 8): 256
    
    With reduce:
    Sum: 15
    Product: 120
    5! = 120
    
    Unary operations:
    neg(5): -5
    neg(-3): 3
    pos(5): 5
    pos(-5): -5
    abs(-10): 10
    abs(7): 7
    
    String operations:
    add('Hello', ' World'): Hello World
    mul('Hi', 3): HiHiHi
    Joined: Python is awesome
    
    List operations:
    add([1,2,3], [4,5,6]): [1, 2, 3, 4, 5, 6]
    mul([1,2], 3): [1, 2, 1, 2, 1, 2]
    Flattened: [1, 2, 3, 4, 5, 6]
    
    Map operations:
    Doubled: [2, 4, 6, 8, 10]
    Squared: [1, 4, 9, 16, 25]
    Negated: [-1, -2, -3, -4, -5]
    
    Calculator functions:
  2. def calculate(a, b, op):

    pass 1 of 4
    116def calculate(a10, b5, op<built-in function add>):117    """Apply operator to two numbers"""118    return op(a10, b5)
    All 4 passes — pass 1 is the card above
    passop
    1<built-in function add>
    2<built-in function sub>
    3<built-in function mul>
    4<built-in function truediv>
  3. print(f"calculate(10, 5, add): {calculate(10, 5, operator.add)}")

    120print(f"calculate(10, 5, add): {calculate(10, 5, operator.add<built-in function add>)}")121print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub<built-in function sub>)}")122print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul)}")
    outputcalculate(10, 5, add): 15
  4. print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub)}")

    120print(f"calculate(10, 5, add): {calculate(10, 5, operator.add)}")121print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub<built-in function sub>)}")122print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul<built-in function mul>)}")123print(f"calculate(10, 5, truediv): {calculate(10, 5, operator.truediv)}")
    outputcalculate(10, 5, sub): 5
  5. print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul)}")

    121print(f"calculate(10, 5, sub): {calculate(10, 5, operator.sub)}")122print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul<built-in function mul>)}")123print(f"calculate(10, 5, truediv): {calculate(10, 5, operator.truediv<built-in function truediv>)}")
    outputcalculate(10, 5, mul): 50
  6. operations ← {'+': <built-in function add>, '-': <built-in function sub>, '*': <built-in function mul>, '/': <built-in function truediv>, '%': <built-in function mod>, '**': <built-in function pow>}

    122print(f"calculate(10, 5, mul): {calculate(10, 5, operator.mul)}")123print(f"calculate(10, 5, truediv): {calculate(10, 5, operator.truediv<built-in function truediv>)}")124125# Operation dispatch126print("\nOperation dispatch:")127128operations→ {'+': <built-in function add>, '-': <built-in function sub>, '*': <built-in function mul>, '/': <built-in function truediv>, '%': <built-in function mod>, '**': <built-in function pow>} = {129    '+': operator.add<built-in function add>,130    '-': operator.sub<built-in function sub>,131    '*': operator.mul<built-in function mul>,132    '/': operator.truediv<built-in function truediv>,133    '%': operator.mod<built-in function mod>,134    '**': operator.pow<built-in function pow>135}136137def eval_expr(a, op, b):138    """Evaluate simple expression"""139    return operations[op](a, b)140141print(f"10 + 5 = {eval_expr(10, '+', 5)}")142print(f"10 - 5 = {eval_expr(10, '-', 5)}")
    outputcalculate(10, 5, truediv): 2.0
    
    Operation dispatch:
  7. def eval_expr(a, op, b):

    pass 1 of 6
    137def eval_expr(a10, op+, b5):138    """Evaluate simple expression"""139    return operations{'+': <built-in function add>, '-': <built-in function sub>, '*': <built-in function mul>, '/': <built-in function truediv>, '%': <built-in function mod>, '**': <built-in function pow>}[op+](a10, b5)
    All 6 passes — pass 1 is the card above
    passaopb
    110+5
    210-5
    310*5
    410/5
    510%3
    62**8
  8. print(f"10 + 5 = {eval_expr(10, '+', 5)}")

    141print(f"10 + 5 = {eval_expr(10, '+', 5)}")142print(f"10 - 5 = {eval_expr(10, '-', 5)}")143print(f"10 * 5 = {eval_expr(10, '*', 5)}")
    output10 + 5 = 15
  9. print(f"10 - 5 = {eval_expr(10, '-', 5)}")

    141print(f"10 + 5 = {eval_expr(10, '+', 5)}")142print(f"10 - 5 = {eval_expr(10, '-', 5)}")143print(f"10 * 5 = {eval_expr(10, '*', 5)}")144print(f"10 / 5 = {eval_expr(10, '/', 5)}")
    output10 - 5 = 5
  10. print(f"10 * 5 = {eval_expr(10, '*', 5)}")

    142print(f"10 - 5 = {eval_expr(10, '-', 5)}")143print(f"10 * 5 = {eval_expr(10, '*', 5)}")144print(f"10 / 5 = {eval_expr(10, '/', 5)}")145print(f"10 % 3 = {eval_expr(10, '%', 3)}")
    output10 * 5 = 50
  11. print(f"10 / 5 = {eval_expr(10, '/', 5)}")

    143print(f"10 * 5 = {eval_expr(10, '*', 5)}")144print(f"10 / 5 = {eval_expr(10, '/', 5)}")145print(f"10 % 3 = {eval_expr(10, '%', 3)}")146print(f"2 ** 8 = {eval_expr(2, '**', 8)}")
    output10 / 5 = 2.0
  12. print(f"10 % 3 = {eval_expr(10, '%', 3)}")

    144print(f"10 / 5 = {eval_expr(10, '/', 5)}")145print(f"10 % 3 = {eval_expr(10, '%', 3)}")146print(f"2 ** 8 = {eval_expr(2, '**', 8)}")
    output10 % 3 = 1
  13. values ← [10, -5, 3, -2, 8], running_sum ← [], total ← 0

    145print(f"10 % 3 = {eval_expr(10, '%', 3)}")146print(f"2 ** 8 = {eval_expr(2, '**', 8)}")147148# Cumulative operations149print("\nCumulative operations:")150151values→ [10, -5, 3, -2, 8] = [10, -5, 3, -2, 8]152153# Cumulative sum154running_sum→ [] = []155total→ 0 = 0156for v in values:
    output2 ** 8 = 256
    
    Cumulative operations:
  14. total ← 10, running_sum ← [10]

    pass 1 of 5
    155total = 0156for v10 in values[10, -5, 3, -2, 8]:157    total→ 10 = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.add(total, v10)158    running_sum→ [10].append(total10)159print(f"Values: {values}")
    All 5 passes — pass 1 is the card above
    passvtotalrunning_sum
    1100 10[] [10]
    2-510 5[10] [10, 5]
    335 8[10, 5] [10, 5, 8]
    4-28 6[10, 5, 8] [10, 5, 8, 6]
    586 14[10, 5, 8, 6] [10, 5, 8, 6, 14]
  15. running_product ← [], product ← 1

    158    running_sum.append(total)159print(f"Values: {values[10, -5, 3, -2, 8]}")160print(f"Running sum: {running_sum[10, 5, 8, 6, 14]}")161162# Cumulative product163running_product→ [] = []164product→ 1 = 1165for v in values:
    outputValues: [10, -5, 3, -2, 8]
    Running sum: [10, 5, 8, 6, 14]
  16. product ← 10, running_product ← [10]

    pass 1 of 5
    164product = 1165for v10 in values[10, -5, 3, -2, 8]:166    product→ 10 = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.mul(product, v10)167    running_product→ [10].append(product10)168print(f"Running product: {running_product}")
    All 5 passes — pass 1 is the card above
    passvproductrunning_product
    1101 10[] [10]
    2-510 -50[10] [10, -50]
    33-50 -150[10, -50] [10, -50, -150]
    4-2-150 300[10, -50, -150] [10, -50, -150, 300]
    58300 2400[10, -50, -150, 300] [10, -50, -150, 300, 2400]
  17. a ← 10, b ← 3, lst ← [1, 2, 3]

    167    running_product.append(product)168print(f"Running product: {running_product[10, -50, -150, 300, 2400]}")169170# In-place operations171print("\nIn-place operations:")172173# iadd (+=)174a→ 10 = 10175a→ 15 = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.iadd(a, 5)176print(f"After iadd(10, 5): {a15}")177178# imul (*=)179b→ 3 = 3180b→ 12 = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.imul(b, 4)181print(f"After imul(3, 4): {b12}")182183# List iadd184lst→ [1, 2, 3] = [1, 2, 3]185lst→ [1, 2, 3, 4, 5] = operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.iadd(lst, [4, 5])186print(f"List after iadd: {lst[1, 2, 3, 4, 5]}")
    outputRunning product: [10, -50, -150, 300, 2400]
    
    In-place operations:
    After iadd(10, 5): 15
    After imul(3, 4): 12
    List after iadd: [1, 2, 3, 4, 5]

Comparison Operations

Function versions of comparison operators:

comparison.py
Replay: real traced execution (multi-file project)
"""Comparison operator functions"""

import operator

# Basic comparisons
print("Basic comparisons:")

# Equality
print(f"eq(5, 5): {operator.eq(5, 5)}")
print(f"eq(5, 3): {operator.eq(5, 3)}")

# Not equal
print(f"ne(5, 3): {operator.ne(5, 3)}")
print(f"ne(5, 5): {operator.ne(5, 5)}")

# Less than
print(f"lt(3, 5): {operator.lt(3, 5)}")
print(f"lt(5, 3): {operator.lt(5, 3)}")

# Less than or equal
print(f"le(5, 5): {operator.le(5, 5)}")
print(f"le(3, 5): {operator.le(3, 5)}")

# Greater than
print(f"gt(5, 3): {operator.gt(5, 3)}")
print(f"gt(3, 5): {operator.gt(3, 5)}")

# Greater than or equal
print(f"ge(5, 5): {operator.ge(5, 5)}")
print(f"ge(5, 3): {operator.ge(5, 3)}")

# Filtering
print("\nFiltering:")

numbers = [1, 5, 10, 15, 20, 25]

# Filter >= 10
greater_eq_10 = [x for x in numbers if operator.ge(x, 10)]
print(f"Numbers >= 10: {greater_eq_10}")

# Filter < 15
less_than_15 = [x for x in numbers if operator.lt(x, 15)]
print(f"Numbers < 15: {less_than_15}")

# Filter == 10
equals_10 = list(filter(lambda x: operator.eq(x, 10), numbers))
print(f"Numbers == 10: {equals_10}")

# String comparisons
print("\nString comparisons:")

words = ['apple', 'banana', 'cherry', 'date']

# Equal to 'banana'
is_banana = list(filter(lambda w: operator.eq(w, 'banana'), words))
print(f"Equal to 'banana': {is_banana}")

# Less than 'cherry'
before_cherry = [w for w in words if operator.lt(w, 'cherry')]
print(f"Before 'cherry': {before_cherry}")

# Custom objects
print("\nCustom objects:")

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person('{self.name}', {self.age})"

people = [
    Person('Alice', 30),
    Person('Bob', 25),
    Person('Charlie', 35)
]

# Find people over 25
over_25 = [p for p in people if operator.gt(p.age, 25)]
print("Over 25:")
for p in over_25:
    print(f"  {p}")

# Find exactly age 30
age_30 = [p for p in people if operator.eq(p.age, 30)]
print(f"\nAge 30: {age_30}")

# Identity and membership
print("\nIdentity and membership:")

a = [1, 2, 3]
b = [1, 2, 3]
c = a

# Identity (is)
print(f"is_(a, b): {operator.is_(a, b)}")
print(f"is_(a, c): {operator.is_(a, c)}")

# Not identity (is not)
print(f"is_not(a, b): {operator.is_not(a, b)}")
print(f"is_not(a, c): {operator.is_not(a, c)}")

# Containment (in)
print(f"contains([1,2,3], 2): {operator.contains([1, 2, 3], 2)}")
print(f"contains([1,2,3], 5): {operator.contains([1, 2, 3], 5)}")
print(f"contains('hello', 'ell'): {operator.contains('hello', 'ell')}")

# Truth testing
print("\nTruth testing:")

# truth() - test if true
print(f"truth(True): {operator.truth(True)}")
print(f"truth(False): {operator.truth(False)}")
print(f"truth([]): {operator.truth([])}")
print(f"truth([1,2,3]): {operator.truth([1, 2, 3])}")
print(f"truth(0): {operator.truth(0)}")
print(f"truth(42): {operator.truth(42)}")

# not_() - logical not
print(f"not_(True): {operator.not_(True)}")
print(f"not_(False): {operator.not_(False)}")
print(f"not_([]): {operator.not_([])}")
print(f"not_([1,2,3]): {operator.not_([1, 2, 3])}")

# Sorting with comparisons
print("\nSorting with comparisons:")

data = [
    {'name': 'Alice', 'score': 85},
    {'name': 'Bob', 'score': 92},
    {'name': 'Charlie', 'score': 78}
]

# Sort by score descending
from functools import cmp_to_key

def compare_score(a, b):
    """Compare by score (descending)"""
    if operator.gt(a['score'], b['score']):
        return -1  # a comes first
    elif operator.lt(a['score'], b['score']):
        return 1   # b comes first
    return 0

sorted_data = sorted(data, key=cmp_to_key(compare_score))
print("Sorted by score (desc):")
for d in sorted_data:
    print(f"  {d}")

# Validation
print("\nValidation:")

def validate_age(age):
    """Validate age is between 0 and 150"""
    return operator.ge(age, 0) and operator.le(age, 150)

ages = [25, -5, 30, 200, 45]
for age in ages:
    valid = validate_age(age)
    print(f"Age {age}: {'valid' if valid else 'invalid'}")

# Range checking
print("\nRange checking:")

def in_range(value, min_val, max_val):
    """Check if value is in range [min, max]"""
    return operator.ge(value, min_val) and operator.le(value, max_val)

print(f"in_range(5, 1, 10): {in_range(5, 1, 10)}")
print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")
print(f"in_range(1, 1, 10): {in_range(1, 1, 10)}")

# Count occurrences
print("\nCount occurrences:")

values = [1, 2, 3, 2, 4, 2, 5]
target = 2

count = sum(1 for v in values if operator.eq(v, target))
print(f"Count of {target}: {count}")

# Count in range
count_range = sum(1 for v in values if operator.ge(v, 2) and operator.le(v, 4))
print(f"Count in [2, 4]: {count_range}")

  1. numbers ← [1, 5, 10, 15, 20, 25], greater_eq_10 ← [10, 15, 20, 25]

    1"""Comparison operator functions"""23import operator45# Basic comparisons6print("Basic comparisons:")78# Equality9print(f"eq(5, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.eq(5, 5)}")10print(f"eq(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.eq(5, 3)}")1112# Not equal13print(f"ne(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ne(5, 3)}")14print(f"ne(5, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ne(5, 5)}")1516# Less than17print(f"lt(3, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(3, 5)}")18print(f"lt(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(5, 3)}")1920# Less than or equal21print(f"le(5, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.le(5, 5)}")22print(f"le(3, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.le(3, 5)}")2324# Greater than25print(f"gt(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.gt(5, 3)}")26print(f"gt(3, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.gt(3, 5)}")2728# Greater than or equal29print(f"ge(5, 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(5, 5)}")30print(f"ge(5, 3): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(5, 3)}")3132# Filtering33print("\nFiltering:")3435numbers→ [1, 5, 10, 15, 20, 25] = [1, 5, 10, 15, 20, 25]3637# Filter >= 1038greater_eq_10→ [10, 15, 20, 25] = [x for x in numbers[1, 5, 10, 15, 20, 25] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(x, 10)]39print(f"Numbers >= 10: {greater_eq_10[10, 15, 20, 25]}")4041# Filter < 1542less_than_15→ [1, 5, 10] = [x for x in numbers[1, 5, 10, 15, 20, 25] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(x, 15)]43print(f"Numbers < 15: {less_than_15[1, 5, 10]}")4445# Filter == 1046equals_10→ [10] = list(filter(lambda x: operator.eq(x, 10), numbers[1, 5, 10, 15, 20, 25]))47print(f"Numbers == 10: {equals_10[10]}")4849# String comparisons50print("\nString comparisons:")5152words→ ['apple', 'banana', 'cherry', 'date'] = ['apple', 'banana', 'cherry', 'date']5354# Equal to 'banana'55is_banana→ ['banana'] = list(filter(lambda w: operator.eq(w, 'banana'), words['apple', 'banana', 'cherry', 'date']))56print(f"Equal to 'banana': {is_banana['banana']}")5758# Less than 'cherry'59before_cherry→ ['apple', 'banana'] = [w for w in words['apple', 'banana', 'cherry', 'date'] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(w, 'cherry')]60print(f"Before 'cherry': {before_cherry['apple', 'banana']}")6162# Custom objects63print("\nCustom objects:")6465class Person:66    def __init__(self, name, age):67        self.name = name68        self.age = age69    70    def __repr__(self):71        return f"Person('{self.name}', {self.age})"7273people = [74    Person('Alice', 30),75    Person('Bob', 25),76    Person('Charlie', 35)77]
    outputBasic comparisons:
    eq(5, 5): True
    eq(5, 3): False
    ne(5, 3): True
    ne(5, 5): False
    lt(3, 5): True
    lt(5, 3): False
    le(5, 5): True
    le(3, 5): True
    gt(5, 3): True
    gt(3, 5): False
    ge(5, 5): True
    ge(5, 3): True
    
    Filtering:
    Numbers >= 10: [10, 15, 20, 25]
    Numbers < 15: [1, 5, 10]
    Numbers == 10: [10]
    
    String comparisons:
    Equal to 'banana': ['banana']
    Before 'cherry': ['apple', 'banana']
    
    Custom objects:
  2. self.name ← Alice, self.age ← 30

    pass 1 of 3
    65class Person:66    def __init__(self(empty), nameAlice, age30):67        self.name→ Alice = nameAlice68        self.age→ 30 = age30
    All 3 passes — pass 1 is the card above
    passnameageself.nameself.age
    1Alice30Alice30
    2Bob25Bob25
    3Charlie35Charlie35
  3. people ← [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)]

    73people→ [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)] = [74    Person('Alice', 30),75    Person('Bob', 25),76    Person('Charlie', 35)77]7879# Find people over 2580over_25→ [Person('Alice', 30), Person('Charlie', 35)] = [p for p in people[Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.gt(p.age(empty), 25)]81print("Over 25:")82for p in over_25:
    outputOver 25:
  4. for p in over_25:

    pass 1 of 2
    81print("Over 25:")82for pPerson('Alice', 30) in over_25[Person('Alice', 30), Person('Charlie', 35)]:83    print(f"  {pPerson('Alice', 30)}")
    output  Person('Alice', 30)
  5. for p in over_25:

    pass 2 of 2
    81print("Over 25:")82for pPerson('Charlie', 35) in over_25[Person('Alice', 30), Person('Charlie', 35)]:83    print(f"  {pPerson('Charlie', 35)}")
    output  Person('Charlie', 35)
  6. age_30 ← [Person('Alice', 30)], a ← [1, 2, 3], b ← [1, 2, 3], c ← [1, 2, 3]

    85# Find exactly age 3086age_30→ [Person('Alice', 30)] = [p for p in people[Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.eq(p.age35, 30)]87print(f"\nAge 30: {age_30[Person('Alice', 30)]}")8889# Identity and membership90print("\nIdentity and membership:")9192a→ [1, 2, 3] = [1, 2, 3]93b→ [1, 2, 3] = [1, 2, 3]94c→ [1, 2, 3] = a[1, 2, 3]9596# Identity (is)97print(f"is_(a, b): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.is_(a[1, 2, 3], b[1, 2, 3])}")98print(f"is_(a, c): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.is_(a[1, 2, 3], c[1, 2, 3])}")99100# Not identity (is not)101print(f"is_not(a, b): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.is_not(a[1, 2, 3], b[1, 2, 3])}")102print(f"is_not(a, c): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.is_not(a[1, 2, 3], c[1, 2, 3])}")103104# Containment (in)105print(f"contains([1,2,3], 2): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.contains([1, 2, 3], 2)}")106print(f"contains([1,2,3], 5): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.contains([1, 2, 3], 5)}")107print(f"contains('hello', 'ell'): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.contains('hello', 'ell')}")108109# Truth testing110print("\nTruth testing:")111112# truth() - test if true113print(f"truth(True): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth(True)}")114print(f"truth(False): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth(False)}")115print(f"truth([]): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth([])}")116print(f"truth([1,2,3]): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth([1, 2, 3])}")117print(f"truth(0): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth(0)}")118print(f"truth(42): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.truth(42)}")119120# not_() - logical not121print(f"not_(True): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.not_(True)}")122print(f"not_(False): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.not_(False)}")123print(f"not_([]): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.not_([])}")124print(f"not_([1,2,3]): {operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.not_([1, 2, 3])}")125126# Sorting with comparisons127print("\nSorting with comparisons:")128129data→ [{'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}, {'name': 'Charlie', 'score': 78}] = [130    {'name': 'Alice', 'score': 85},131    {'name': 'Bob', 'score': 92},132    {'name': 'Charlie', 'score': 78}133]134135# Sort by score descending136from functools import cmp_to_key137138def compare_score(a, b):139    """Compare by score (descending)"""140    if operator.gt(a['score'], b['score']):141        return -1  # a comes first142    elif operator.lt(a['score'], b['score']):143        return 1   # b comes first144    return 0145146sorted_data = sorted(data[{'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}, {'name': 'Charlie', 'score': 78}], key=cmp_to_key(compare_score⟨function compare_score A⟩))147print("Sorted by score (desc):")
    output
    Age 30: [Person('Alice', 30)]
    
    Identity and membership:
    is_(a, b): False
    is_(a, c): True
    is_not(a, b): True
    is_not(a, c): False
    contains([1,2,3], 2): True
    contains([1,2,3], 5): False
    contains('hello', 'ell'): True
    
    Truth testing:
    truth(True): True
    truth(False): False
    truth([]): False
    truth([1,2,3]): True
    truth(0): False
    truth(42): True
    not_(True): False
    not_(False): True
    not_([]): True
    not_([1,2,3]): False
    
    Sorting with comparisons:
  7. def compare_score(a, b):

    pass 1 of 3
    138def compare_score(a{'name': 'Bob', 'score': 92}, b{'name': 'Alice', 'score': 85}):139    """Compare by score (descending)"""140    if operator.gt(a['score'], b['score']):
    All 3 passes — pass 1 is the card above
    passaba[’score’]b[’score’]
    1{'name': 'Bob', 'score': 92}{'name': 'Alice', 'score': 85}9285
    2{'name': 'Charlie', 'score': 78}{'name': 'Bob', 'score': 92}7892
    3{'name': 'Charlie', 'score': 78}{'name': 'Alice', 'score': 85}7885
  8. if operator.gt(a['score'], b['score']):

    139"""Compare by score (descending)"""140if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.gt(a['score']92, b['score']85):141    return -1  # a comes first142elif operator.lt(a['score'], b['score']):
  9. elif operator.lt(a['score'], b['score']):

    pass 1 of 2
    141    return -1  # a comes first142elif operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(a['score']78, b['score']92):143    return 1   # b comes first144return 0
  10. elif operator.lt(a['score'], b['score']):

    pass 2 of 2
    141    return -1  # a comes first142elif operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.lt(a['score']78, b['score']85):143    return 1   # b comes first144return 0
  11. sorted_data ← [{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Charlie', 'score': 78}]

    146sorted_data→ [{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Charlie', 'score': 78}] = sorted(data[{'name': 'Alice', 'score': 85}, {'name': 'Bob', 'score': 92}, {'name': 'Charlie', 'score': 78}], key=cmp_to_key(compare_score⟨function compare_score A⟩))147print("Sorted by score (desc):")148for d in sorted_data:
    outputSorted by score (desc):
  12. for d in sorted_data:

    pass 1 of 3
    147print("Sorted by score (desc):")148for d{'name': 'Bob', 'score': 92} in sorted_data[{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Charlie', 'score': 78}]:149    print(f"  {d{'name': 'Bob', 'score': 92}}")
    output  {'name': 'Bob', 'score': 92}
    All 3 passes — pass 1 is the card above
    passd
    1{'name': 'Bob', 'score': 92}
    2{'name': 'Alice', 'score': 85}
    3{'name': 'Charlie', 'score': 78}
  13. ages ← [25, -5, 30, 200, 45]

    151# Validation152print("\nValidation:")153154def validate_age(age):155    """Validate age is between 0 and 150"""156    return operator.ge(age, 0) and operator.le(age, 150)157158ages→ [25, -5, 30, 200, 45] = [25, -5, 30, 200, 45]159for age in ages:
    output
    Validation:
  14. for age in ages:

    pass 1 of 5
    158ages = [25, -5, 30, 200, 45]159for age25 in ages[25, -5, 30, 200, 45]:160    valid = validate_age(age25)161    print(f"Age {age}: {'valid' if valid else 'invalid'}")
    All 5 passes — pass 1 is the card above
    passage
    125
    2-5
    330
    4200
    545
  15. def validate_age(age):

    pass 1 of 5
    154def validate_age(age25):155    """Validate age is between 0 and 150"""156    return operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(age25, 0) and operator.le(age, 150)
    All 5 passes — pass 1 is the card above
    passage
    125
    2-5
    330
    4200
    545
  16. valid ← True

    159for age in ages:160    valid→ True = validate_age(age25)161    print(f"Age {age25}: {'valid' if validTrue else 'invalid'}")
    outputAge 25: valid
  17. valid ← False

    159for age in ages:160    valid→ False = validate_age(age-5)161    print(f"Age {age-5}: {'valid' if validFalse else 'invalid'}")
    outputAge -5: invalid
  18. valid ← True

    159for age in ages:160    valid→ True = validate_age(age30)161    print(f"Age {age30}: {'valid' if validTrue else 'invalid'}")
    outputAge 30: valid
  19. valid ← False

    159for age in ages:160    valid→ False = validate_age(age200)161    print(f"Age {age200}: {'valid' if validFalse else 'invalid'}")
    outputAge 200: invalid
  20. valid ← True

    159for age in ages:160    valid→ True = validate_age(age45)161    print(f"Age {age45}: {'valid' if validTrue else 'invalid'}")
    outputAge 45: valid
  21. print(" Range checking:")

    163# Range checking164print("\nRange checking:")165166def in_range(value, min_val, max_val):167    """Check if value is in range [min, max]"""168    return operator.ge(value, min_val) and operator.le(value, max_val)169170print(f"in_range(5, 1, 10): {in_range(5, 1, 10)}")171print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")
    output
    Range checking:
  22. def in_range(value, min_val, max_val):

    pass 1 of 3
    166def in_range(value5, min_val1, max_val10):167    """Check if value is in range [min, max]"""168    return operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(value5, min_val1) and operator.le(value, max_val10)
    All 3 passes — pass 1 is the card above
    passvalue
    15
    215
    31
  23. print(f"in_range(5, 1, 10): {in_range(5, 1, 10)}")

    170print(f"in_range(5, 1, 10): {in_range(5, 1, 10)}")171print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")172print(f"in_range(1, 1, 10): {in_range(1, 1, 10)}")
    outputin_range(5, 1, 10): True
  24. print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")

    170print(f"in_range(5, 1, 10): {in_range(5, 1, 10)}")171print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")172print(f"in_range(1, 1, 10): {in_range(1, 1, 10)}")
    outputin_range(15, 1, 10): False
  25. values ← [1, 2, 3, 2, 4, 2, 5], target ← 2, count ← 3, count_range ← 5

    171print(f"in_range(15, 1, 10): {in_range(15, 1, 10)}")172print(f"in_range(1, 1, 10): {in_range(1, 1, 10)}")173174# Count occurrences175print("\nCount occurrences:")176177values→ [1, 2, 3, 2, 4, 2, 5] = [1, 2, 3, 2, 4, 2, 5]178target→ 2 = 2179180count→ 3 = sum(1 for v in values[1, 2, 3, 2, 4, 2, 5] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.eq(v, target2))181print(f"Count of {target2}: {count3}")182183# Count in range184count_range→ 5 = sum(1 for v in values[1, 2, 3, 2, 4, 2, 5] if operator<module 'operator' from '/usr/local/lib/python3.12/operator.py'>.ge(v, 2) and operator.le(v, 4))185print(f"Count in [2, 4]: {count_range5}")
    outputin_range(1, 1, 10): True
    
    Count occurrences:
    Count of 2: 3
    Count in [2, 4]: 5

Exercise: practical.py

Sort a list of records by multiple fields using itemgetter and attrgetter