Utilities
Operator Module
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:
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}")
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:for s in sorted_by_grade:
pass 1 of 345print("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 pass s1 {'name': 'Bob', 'grade': 78} 2 {'name': 'Charlie', 'grade': 85} 3 {'name': 'Alice', 'grade': 92} 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:for s in sorted_by_name:
pass 1 of 351print("\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 pass s1 {'name': 'Alice', 'grade': 92} 2 {'name': 'Bob', 'grade': 78} 3 {'name': 'Charlie', 'grade': 85} 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:for d in sorted_data:
pass 1 of 368print("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 pass d1 {'name': 'Charlie', 'scores': [78, 95]} 2 {'name': 'Alice', 'scores': [85, 90]} 3 {'name': 'Bob', 'scores': [92, 88]} 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:for r in sorted_by_age:
pass 1 of 383print("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 pass r1 ('Bob', 25, 'LA') 2 ('Alice', 30, 'NYC') 3 ('Charlie', 35, 'Chicago') 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:for r in sorted_multi:
pass 1 of 389print("\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 pass r1 ('Charlie', 35, 'Chicago') 2 ('Bob', 25, 'LA') 3 ('Alice', 30, 'NYC') 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:total ← 80
pass 1 of 2144for 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: $80total ← 35
pass 2 of 2144for 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
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:for s in sorted_by_grade:
pass 1 of 345print("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 pass s1 {'name': 'Bob', 'grade': 78} 2 {'name': 'Charlie', 'grade': 85} 3 {'name': 'Alice', 'grade': 92} 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:for s in sorted_by_name:
pass 1 of 351print("\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 pass s1 {'name': 'Alice', 'grade': 92} 2 {'name': 'Bob', 'grade': 78} 3 {'name': 'Charlie', 'grade': 85} 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:for d in sorted_data:
pass 1 of 368print("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 pass d1 {'name': 'Charlie', 'scores': [78, 95]} 2 {'name': 'Alice', 'scores': [85, 90]} 3 {'name': 'Bob', 'scores': [92, 88]} 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:for r in sorted_by_age:
pass 1 of 383print("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 pass r1 ('Bob', 25, 'LA') 2 ('Alice', 30, 'NYC') 3 ('Charlie', 35, 'Chicago') 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:for r in sorted_multi:
pass 1 of 389print("\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 pass r1 ('Charlie', 35, 'Chicago') 2 ('Bob', 25, 'LA') 3 ('Alice', 30, 'NYC') 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:total ← 80
pass 1 of 2144for 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: $80total ← 35
pass 2 of 2144for 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
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:for s in sorted_by_grade:
pass 1 of 345print("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 pass s1 {'name': 'Bob', 'grade': 78} 2 {'name': 'Charlie', 'grade': 85} 3 {'name': 'Alice', 'grade': 92} 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:for s in sorted_by_name:
pass 1 of 351print("\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 pass s1 {'name': 'Alice', 'grade': 92} 2 {'name': 'Bob', 'grade': 78} 3 {'name': 'Charlie', 'grade': 85} 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:for d in sorted_data:
pass 1 of 368print("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 pass d1 {'name': 'Charlie', 'scores': [78, 95]} 2 {'name': 'Alice', 'scores': [85, 90]} 3 {'name': 'Bob', 'scores': [92, 88]} 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:for r in sorted_by_age:
pass 1 of 383print("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 pass r1 ('Bob', 25, 'LA') 2 ('Alice', 30, 'NYC') 3 ('Charlie', 35, 'Chicago') 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:for r in sorted_multi:
pass 1 of 389print("\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 pass r1 ('Charlie', 35, 'Chicago') 2 ('Bob', 25, 'LA') 3 ('Alice', 30, 'NYC') 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:total ← 80
pass 1 of 2144for 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: $80total ← 35
pass 2 of 2144for 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}")
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:self.name ← Alice, self.age ← 30
pass 1 of 49class Person:10 def __init__(self(empty), nameAlice, age30):11 self.name→ Alice = nameAlice12 self.age→ 30 = age30All 4 passes — pass 1 is the card above pass nameageself.nameself.age1 Alice 30 Alice 30 2 Charlie 35 Charlie 35 3 Alice 30 Alice 30 4 Bob 25 Bob 25 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: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:for p in sorted_by_name:
pass 1 of 343print("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 pass p1 Person('Alice', 30) 2 Person('Bob', 25) 3 Person('Charlie', 35) 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:for p in sorted_by_age:
pass 1 of 349print("\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 pass p1 Person('Bob', 25) 2 Person('Alice', 30) 3 Person('Charlie', 35) 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:self.city ← NYC, self.zip ← 10001
pass 1 of 356class Address:57 def __init__(self(empty), cityNYC, zip_code10001):58 self.city→ NYC = cityNYC59 self.zip→ 10001 = zip_code10001All 3 passes — pass 1 is the card above pass cityzip_codeself.cityself.zip1 NYC 10001 NYC 10001 2 LA 90001 LA 90001 3 Chicago 60601 Chicago 60601 self.name ← Alice, self.address ← Address('NYC', '10001')
pass 1 of 364class 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 pass nameaddressself.nameself.address1 Alice Address('NYC', '10001') Alice Address('NYC', '10001') 2 Bob Address('LA', '90001') Bob Address('LA', '90001') 3 Charlie Address('Chicago', '60601') Charlie Address('Chicago', '60601') 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:for emp in sorted_by_city:
pass 1 of 385print("\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 pass emp1 Employee('Charlie', Address('Chicago', '60601')) 2 Employee('Bob', Address('LA', '90001')) 3 Employee('Alice', Address('NYC', '10001')) 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:self.name ← Widget, self.price ← 29.99, self.quantity ← 100
pass 1 of 392class Product:93 def __init__(self(empty), nameWidget, price29.99, quantity100):94 self.name→ Widget = nameWidget95 self.price→ 29.99 = price29.9996 self.quantity→ 100 = quantity100All 3 passes — pass 1 is the card above pass namepricequantityself.nameself.priceself.quantity1 Widget 29.99 100 Widget 29.99 100 2 Gadget 49.99 50 Gadget 49.99 50 3 Tool 19.99 200 Tool 19.99 200 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:self.name ← Alice, self.grade ← 92
pass 1 of 3116class Student:117 def __init__(self⟨Student A⟩, nameAlice, grade92):118 self.name→ Alice = nameAlice119 self.grade→ 92 = grade92All 3 passes — pass 1 is the card above pass selfnamegradeself.nameself.grade1 ⟨Student A⟩ Alice 92 Alice 92 2 ⟨Student B⟩ Bob 85 Bob 85 3 ⟨Student C⟩ Charlie 78 Charlie 78 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:self.name ← Review code, self.priority ← 3, self.completed ← False
pass 1 of 3142class Task:143 def __init__(self(empty), nameReview code, priority3, completedFalse):144 self.name→ Review code = nameReview code145 self.priority→ 3 = priority3146 self.completed→ False = completedFalseAll 3 passes — pass 1 is the card above pass nameprioritycompletedself.nameself.priorityself.completed1 Review code 3 False Review code 3 False 2 Fix bug 1 True Fix bug 1 True 3 Write tests 2 False Write tests 2 False 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: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)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:self.category ← A, self.value ← 10
pass 1 of 5172class Record:173 def __init__(self⟨Record D⟩, categoryA, value10):174 self.category→ A = categoryA175 self.value→ 10 = value10All 5 passes — pass 1 is the card above pass selfcategoryvalueself.categoryself.value1 ⟨Record D⟩ A 10 A 10 2 ⟨Record E⟩ B 20 B 20 3 ⟨Record F⟩ A 15 A 15 4 ⟨Record G⟩ B 25 B 25 5 ⟨Record H⟩ A 5 A 5 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'))values ← [10, 15, 5]
pass 1 of 2188for 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=30values ← [20, 25]
pass 2 of 2188for 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=45print(" 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:self.name ← Login, self.timestamp ← 2024-01-15 10:30:00
pass 1 of 3196class 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:00All 3 passes — pass 1 is the card above pass nametimestampself.nameself.timestamp1 Login 2024-01-15 10:30:00 Login 2024-01-15 10:30:00 2 Purchase 2024-01-15 11:45:00 Purchase 2024-01-15 11:45:00 3 Logout 2024-01-15 09:15:00 Logout 2024-01-15 09:15:00 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:for e in sorted_events:
pass 1 of 3212print("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 pass e1 Event('Logout', 2024-01-15 09:15:00) 2 Event('Login', 2024-01-15 10:30:00) 3 Event('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}")
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:self.value ← 10
pass 1 of 360class Counter:61 def __init__(self(empty), value10=0):62 self.value→ 10 = value10All 3 passes — pass 1 is the card above pass valueself.value1 10 10 2 20 20 3 30 30 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:for c in counters:
pass 1 of 378reset_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 pass ccounters1 Counter(10) [Counter(10), Counter(20), Counter(30)] 2 Counter(20) [Counter(0), Counter(20), Counter(30)] 3 Counter(30) [Counter(0), Counter(0), Counter(30)] self.value ← 0
pass 1 of 368def reset(selfCounter(10)):69 self.value→ 0 = 070 return self.value0All 3 passes — pass 1 is the card above pass selfself.value1 Counter(10) 0 2 Counter(20) 0 3 Counter(30) 0 c ← Counter(0)
79for c in counters:80 reset_all(c→ Counter(0))c ← Counter(0)
79for c in counters:80 reset_all(c→ Counter(0))c ← Counter(0)
79for c in counters:80 reset_all(c→ Counter(0))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)]for c in counters:
pass 1 of 385increment_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 pass counters1 [Counter(0), Counter(0), Counter(0)] 2 [Counter(5), Counter(0), Counter(0)] 3 [Counter(5), Counter(5), Counter(0)] self.value ← 5
pass 1 of 364def increment(selfCounter(0), amount5=1):65 self.value→ 5 += amount566 return self.value5All 3 passes — pass 1 is the card above pass self.value1 0 → 5 2 0 → 5 3 0 → 5 c ← Counter(5)
86for c in counters:87 increment_5(c→ Counter(5))c ← Counter(5)
86for c in counters:87 increment_5(c→ Counter(5))c ← Counter(5)
86for c in counters:87 increment_5(c→ Counter(5))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:lst ← [1, 2, 3]
pass 1 of 397sort_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 pass listslst1 [[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] 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]]lst ← [1, 2, 3, 10]
pass 1 of 3104append_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 pass listslst1 [[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] 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:self.name ← Fix bug, self.priority ← 1
pass 1 of 4132class Task:133 def __init__(self(empty), nameFix bug, priority1):134 self.name→ Fix bug = nameFix bug135 self.priority→ 1 = priority1All 4 passes — pass 1 is the card above pass namepriorityself.nameself.priority1 Fix bug 1 Fix bug 1 2 Write docs 3 Write docs 3 3 Review code 2 Review code 2 4 Update tests 4 Update tests 4 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)]def is_high_priority(self):
pass 1 of 4137def is_high_priority(selfTask('Fix bug', 1)):138 return self.priority1 <= 2All 4 passes — pass 1 is the card above pass selfself.priority1 Task('Fix bug', 1) 1 2 Task('Write docs', 3) 3 3 Task('Review code', 2) 2 4 Task('Update tests', 4) 4 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:for t in high_priority:
pass 1 of 2154print("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)for t in high_priority:
pass 2 of 2154print("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)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:self.value ← hello
pass 1 of 4161class Text:162 def __init__(self(empty), value hello ):163 self.value→ hello = value helloAll 4 passes — pass 1 is the card above pass valueself.value1 hello hello 2 hello hello 3 HELLO HELLO 4 OLLEH OLLEH 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:for op in operations:
pass 1 of 3186result = 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 pass opresultselfself.valueself.value[::-1]1 operator.methodcaller('strip') Text(' hello ') Text(' hello ') hello — 2 operator.methodcaller('upper') Text('hello') Text('hello') hello — 3 operator.methodcaller('reverse') Text('HELLO') Text('HELLO') — OLLEH def strip(self):
171def strip(selfText(' hello ')):172 return Text(self.value hello .strip())result ← Text('hello')
187for op in operations:188 result→ Text('hello') = op(result)def upper(self):
165def upper(selfText('hello')):166 return Text(self.valuehello.upper())result ← Text('HELLO')
187for op in operations:188 result→ Text('HELLO') = op(result)def reverse(self):
168def reverse(selfText('HELLO')):169 return Text(self.value[::-1]OLLEH)result ← Text('OLLEH')
187for op in operations:188 result→ Text('OLLEH') = op(result)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}")
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:def calculate(a, b, op):
pass 1 of 4116def 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 pass op1 <built-in function add> 2 <built-in function sub> 3 <built-in function mul> 4 <built-in function truediv> 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): 15print(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): 5print(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): 50operations ← {'+': <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:def eval_expr(a, op, b):
pass 1 of 6137def 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 pass aopb1 10 + 5 2 10 - 5 3 10 * 5 4 10 / 5 5 10 % 3 6 2 ** 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 = 15print(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 = 5print(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 = 50print(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.0print(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 = 1values ← [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:total ← 10, running_sum ← [10]
pass 1 of 5155total = 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 pass vtotalrunning_sum1 10 0 → 10 [] → [10] 2 -5 10 → 5 [10] → [10, 5] 3 3 5 → 8 [10, 5] → [10, 5, 8] 4 -2 8 → 6 [10, 5, 8] → [10, 5, 8, 6] 5 8 6 → 14 [10, 5, 8, 6] → [10, 5, 8, 6, 14] 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]product ← 10, running_product ← [10]
pass 1 of 5164product = 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 pass vproductrunning_product1 10 1 → 10 [] → [10] 2 -5 10 → -50 [10] → [10, -50] 3 3 -50 → -150 [10, -50] → [10, -50, -150] 4 -2 -150 → 300 [10, -50, -150] → [10, -50, -150, 300] 5 8 300 → 2400 [10, -50, -150, 300] → [10, -50, -150, 300, 2400] 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}")
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:self.name ← Alice, self.age ← 30
pass 1 of 365class Person:66 def __init__(self(empty), nameAlice, age30):67 self.name→ Alice = nameAlice68 self.age→ 30 = age30All 3 passes — pass 1 is the card above pass nameageself.nameself.age1 Alice 30 Alice 30 2 Bob 25 Bob 25 3 Charlie 35 Charlie 35 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:for p in over_25:
pass 1 of 281print("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)for p in over_25:
pass 2 of 281print("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)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:def compare_score(a, b):
pass 1 of 3138def 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 pass aba[’score’]b[’score’]1 {'name': 'Bob', 'score': 92} {'name': 'Alice', 'score': 85} 92 85 2 {'name': 'Charlie', 'score': 78} {'name': 'Bob', 'score': 92} 78 92 3 {'name': 'Charlie', 'score': 78} {'name': 'Alice', 'score': 85} 78 85 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']):elif operator.lt(a['score'], b['score']):
pass 1 of 2141 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 0elif operator.lt(a['score'], b['score']):
pass 2 of 2141 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 0sorted_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):for d in sorted_data:
pass 1 of 3147print("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 pass d1 {'name': 'Bob', 'score': 92} 2 {'name': 'Alice', 'score': 85} 3 {'name': 'Charlie', 'score': 78} 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:for age in ages:
pass 1 of 5158ages = [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 pass age1 25 2 -5 3 30 4 200 5 45 def validate_age(age):
pass 1 of 5154def 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 pass age1 25 2 -5 3 30 4 200 5 45 valid ← True
159for age in ages:160 valid→ True = validate_age(age25)161 print(f"Age {age25}: {'valid' if validTrue else 'invalid'}")outputAge 25: validvalid ← 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: invalidvalid ← True
159for age in ages:160 valid→ True = validate_age(age30)161 print(f"Age {age30}: {'valid' if validTrue else 'invalid'}")outputAge 30: validvalid ← False
159for age in ages:160 valid→ False = validate_age(age200)161 print(f"Age {age200}: {'valid' if validFalse else 'invalid'}")outputAge 200: invalidvalid ← True
159for age in ages:160 valid→ True = validate_age(age45)161 print(f"Age {age45}: {'valid' if validTrue else 'invalid'}")outputAge 45: validprint(" 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:def in_range(value, min_val, max_val):
pass 1 of 3166def 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 pass value1 5 2 15 3 1 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): Trueprint(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): Falsevalues ← [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