Programs with Packing
Six programs, and every one of them is a program you could already write — three lines shorter and considerably easier to read. That is all unpacking ever does: it does not make new things possible, it makes the obvious thing sayable in one line.
1Program 1 — a loop that unpacks as it goes
A list holds small lists, each a name and a mark. Print each name with its mark.
# looping over pairs, unpacked as they arrive
students = [['Asha', 72], ['Ravi', 65], ['Meera', 88]]
for name, marks in students:
print(name, 'scored', marks)Asha scored 72 Ravi scored 65 Meera scored 88
for name, marks in students:Two loop variables, not one. Each round hands out one item of students — which is itself a list of two — and unpacks it into the two names, exactly as an ordinary assignment would.
Compare it with the version you would have written a chapter ago, and the argument makes itself:
# the same loop, without unpacking
students = [['Asha', 72], ['Ravi', 65], ['Meera', 88]]
for student in students:
name = student[0]
marks = student[1]
print(name, 'scored', marks)Asha scored 72 Ravi scored 65 Meera scored 88
students and that round raises ValueError: too many values to unpack (expected 2) — halfway through, after the earlier lines have already printed. The loop unpacks each item as it arrives, so a bad item is only found when it is reached.2Program 2 — one typed line, several values
Ask the user to type a name and an age on one line, and use them separately.
# one line of input, split and unpacked
line = input('Enter your name and age, separated by a space: ')
name, age = line.split()
print('Name:', name)
print('Age next year:', int(age) + 1)Enter your name and age, separated by a space: Asha 16 Name: Asha Age next year: 17
Enter your name and age, separated by a space: Asha Kumari 16 ValueError: too many values to unpack (expected 2)
The failure is the program doing its job: it asked for two things and got three. Where that is likely, the star handles it — *names, age = line.split() takes any number of name parts and the age from the end.
# a name of any length, and an age at the end
line = input('Enter your full name and age: ')
*names, age = line.split()
print('Name parts:', names)
print('Age:', int(age))Enter your full name and age: Asha Kumari Verma 16 Name parts: ['Asha', 'Kumari', 'Verma'] Age: 16
3Program 3 — swapping and rotating
Ask for two numbers, swap them, then rotate three values one place along.
# swapping two, and rotating three
x = int(input('First number: '))
y = int(input('Second number: '))
print('Before: x =', x, 'y =', y)
x, y = y, x
print('After: x =', x, 'y =', y)
a = 1
b = 2
c = 3
a, b, c = c, a, b
print('Rotated:', a, b, c)First number: 10 Second number: 20 Before: x = 10 y = 20 After: x = 20 y = 10 Rotated: 3 1 2
temp and three careful lines.4Program 4 — reversing a list, without a temp
Reverse a list in place by swapping from both ends — the program from the lists chapter, with the swap written Python's way.
# reverse a list in place, swapping with no temp variable
numbers = [10, 20, 30, 40, 50]
print('Before:', numbers)
for i in range(len(numbers) // 2):
last = len(numbers) - 1 - i
numbers[i], numbers[last] = numbers[last], numbers[i]
print('After: ', numbers)Before: [10, 20, 30, 40, 50] After: [50, 40, 30, 20, 10]
Three lines became one, and the one that is left says swap these two rather than put this here, that there, and the saved one back. The temp version is still the one to write when a question says “without using a third variable” is not allowed — but this is what you would write for yourself.
5Program 5 — putting two answers in one place
Find the largest and the smallest of a list, and report them as a pair.
# two answers, packed together and unpacked again
marks = [56, 91, 43, 78, 65]
answer = max(marks), min(marks)
print('The pair is', answer)
highest, lowest = answer
print('Highest:', highest)
print('Lowest: ', lowest)
print('Difference:', highest - lowest)The pair is (91, 43) Highest: 91 Lowest: 43 Difference: 48
return max(marks), min(marks). Functions are Class 12; the idea that makes it work is on this page.6Program 6 — a lined-up table from a list of pairs
Print a price list from a list of item-and-price pairs, with the columns lined up and the total at the bottom.
# a price list, from a list of pairs
items = [['Notebook', 45.5], ['Pen', 12.0], ['Geometry box', 149.75]]
total = 0
print(f'{"Item":15}{"Price":>10}')
for name, price in items:
total = total + price
print(f'{name:15}{price:10.2f}')
print(f'{"Total":15}{total:10.2f}')Item Price Notebook 45.50 Pen 12.00 Geometry box 149.75 Total 207.25
Everything from the last two chapters at once: a list of pairs, unpacked by the loop, printed with f-string widths, and a total collected on the way. name and price exist because the loop header unpacked them — without that, every line would carry item[0] and item[1] and be harder to read for no gain.
7Recap
The most useful line in the chapter. A list of pairs walks with two loop variables, and cannot fall out of step the way parallel lists can.
One typed line becomes named values. Use a star when the number of pieces is not fixed.
Both old values are packed before either name changes — and it works for three values, and for list positions.
max(marks), min(marks) is one value holding two, unpacked where it is needed. That is how functions will return pairs.
- 1
Given a list of city-and-temperature pairs, print the hottest city.
Hint · A champion loop with two loop variables — and the champion is a pair, so keep both parts.
- 2
Ask the user for three numbers on one line and print their total.
Hint ·
a, b, c = line.split(), and remember all three are still text. - 3
Swap the first and last items of a list without a
temp.Hint ·
numbers[0], numbers[-1] = numbers[-1], numbers[0]. - 4
From a list of item-and-price pairs, build two separate lists — one of items and one of prices.
Hint · One loop with two loop variables and two
append()calls. - 5
Rotate the values of four variables one place along, in one line.
Hint ·
a, b, c, d = d, a, b, c— and check it by printing before and after.
students holds [['Asha', 72], ['Ravi', 65]]. What does for name, marks in students: do?
Why does numbers[i], numbers[last] = numbers[last], numbers[i] need no temp?
line.split() gives three pieces and the program says name, age = line.split(). What happens?