Working with a List of Numbers
A month of card payments is a list of numbers, and the questions you ask of it are the questions programs answer every day. How much did I spend in total? What was the biggest payment? What does a typical one look like? Python has a built-in tool for each of these, and a compact way to build a new list out of an old one.
Think of reading a till receipt: the total at the bottom, a quick scan for the biggest line, maybe circling everything over twenty. This page does each of those in one line of Python.
A Month of Amounts
Here are five payments from a month of spending, typed in as a list. They are money, so each one is a Decimal made from text, as Chapter 2 recommended. They are written as positive numbers for now; in the bank's own file, in Chapter 7, spending appears with a minus sign.
from decimal import Decimal amounts = [Decimal("54.30"), Decimal("45.00"), Decimal("4.20"), Decimal("61.75"), Decimal("12.50")] print(amounts)
[Decimal('54.30'), Decimal('45.00'), Decimal('4.20'), Decimal('61.75'), Decimal('12.50')]
A list may be split over two lines like this, as long as the break comes inside the brackets: Python knows the list is not finished until the closing bracket.
sum, max, min and len
Four built-in functions answer the first questions directly. sum adds every item and gives the total, 177.75. max and min give the largest and smallest item. len, as before, counts the items. The average is the total divided by the count, and it is formatted to two places only when it is printed: store exact, show rounded.
from decimal import Decimal amounts = [Decimal("54.30"), Decimal("45.00"), Decimal("4.20"), Decimal("61.75"), Decimal("12.50")] total = sum(amounts) print(f"Total spent: {total}") print(f"Biggest payment: {max(amounts)}") print(f"Smallest payment: {min(amounts)}") print(f"Average payment: {total / len(amounts):.2f}")
Total spent: 177.75 Biggest payment: 61.75 Smallest payment: 4.20 Average payment: 35.55
What sum Is Doing
sum is not magic. It is exactly the running total from Topic 3, packaged as a function. The version below writes the loop out by hand and arrives at the same 177.75. When you meet a built-in that seems clever, it usually helps to imagine the plain loop it stands for.
from decimal import Decimal amounts = [Decimal("54.30"), Decimal("45.00"), Decimal("4.20"), Decimal("61.75"), Decimal("12.50")] total = Decimal("0") for amount in amounts: total = total + amount print(total)
177.75
A First List Comprehension
Often you want a new list made from an old one: only the payments over 20, say. The loop way is to start an empty list and append each match. Python also offers a one-line form called a list comprehension. Read it aloud as "each amount, for every amount in amounts, if the amount is over twenty". It builds exactly the list the loop would.
from decimal import Decimal amounts = [Decimal("54.30"), Decimal("45.00"), Decimal("4.20"), Decimal("61.75"), Decimal("12.50")] big = [] for amount in amounts: if amount > 20: big.append(amount) print(big) big = [amount for amount in amounts if amount > 20] print(big)
[Decimal('54.30'), Decimal('45.00'), Decimal('61.75')]
[Decimal('54.30'), Decimal('45.00'), Decimal('61.75')]
Comprehensions are a shorthand, not a requirement. You will meet them constantly in other people's code, so being able to read one matters. When you write your own, the plain loop is always allowed, and it is often clearer when the condition gets complicated.
- "sum needs a loop around it." sum walks the list itself. Write the loop only when you need something sum cannot do.
- "The average should be rounded before it is stored." Keep the exact value and round when you show it, so later arithmetic stays exact.
- "List comprehensions are required in real code." They are a shorthand. A loop that does the same is correct, and sometimes clearer.
- Totals, extremes, averages and filters answer most first questions about any data, and each is one line.
- Comprehensions appear constantly in other people's Python. Reading one aloud, as a sentence, makes them easy to follow.
Knowledge Check
What does sum(amounts) do?
- Counts how many amounts are in the list
- Adds every amount in the list and gives the total
- Gives the largest amount found in the list
- Rounds each amount before adding them up
How is the average worked out on this page?
max(amounts)divided bymin(amounts)len(amounts)divided bysum(amounts)sum(amounts)divided bylen(amounts)sum(amounts)rounded to two decimal places
What does [a for a in amounts if a > 20] produce?
- The number of amounts that are greater than 20
- The same list, sorted from largest to smallest
- A new list of only the amounts greater than 20
- The original list, with every amount above 20 removed
Why are the amounts written as Decimal("54.30") rather than 54.30?
- Because sum refuses to add plain numbers together
- Because Decimal amounts print with a currency symbol
- Because lists can only hold Decimal values
- They are money, and Decimal from text keeps cents exact
You got correct