Packing Values Together
Unpacking was commas on the left. Packing is commas on the right: several values, one name, and Python quietly builds a tuple to hold them. It takes one line to explain, and then it explains something the course has asked you to take on trust twice.
1Commas on the right make a tuple
# commas on the right make a tuple
point = 3, 7
print(point)
print(type(point))
print('The first value is', point[0])(3, 7) <class 'tuple'> The first value is 3
(3, 7) and 3, 7 build the same thing, because what makes a tuple is the comma. Python prints it back with brackets round it, which is why you have always seen them.And that explains a thing you met in the tuples lesson and probably filed under “odd”: a single value with a trailing comma is a tuple of one, while the same value in brackets with no comma is just the value.
# the comma, not the brackets
a = 5,
b = (5)
c = (5,)
print(a, type(a))
print(b, type(b))
print(c, type(c))(5,) <class 'tuple'> 5 <class 'int'> (5,) <class 'tuple'>
2Packing and unpacking, one after the other
# packing and unpacking, one after the other
student = 'Asha', 11, 91
print(student)
name, cls, marks = student
print(name, 'of class', cls, 'scored', marks)('Asha', 11, 91)
Asha of class 11 scored 91Three values packed into one name, then unpacked into three names again. Notice what a tuple is good for here: the three belong together — a name, a class and a mark are one student — and packing them says so in a way three separate variables cannot.
3At last: why x, y = y, x works
The Sample Programs chapter showed the swap with a temp variable and mentioned this one-liner as Python's shortcut. The list chapter used it again. Here is what it actually does — and it is nothing new, just one of each idea from these two pages:
# the swap, explained at last
x = 10
y = 20
print('Before: x =', x, 'y =', y)
x, y = y, x
print('After: x =', x, 'y =', y)Before: x = 10 y = 20 After: x = 20 y = 10
Take that middle line in two halves, in the order Python does them:
# what the swap really does, in two halves
x = 10
y = 20
packed = y, x
print('The right side is packed first:', packed)
x, y = packed
print('Then unpacked into the names: x =', x, 'y =', y)The right side is packed first: (20, 10) Then unpacked into the names: x = 20 y = 10
packed = y, xThe right-hand side runs FIRST, exactly as it does in every assignment — that rule is from the very first variables lesson. It packs the two CURRENT values, 20 and 10, into a tuple. Neither name has changed yet.
x, y = packedNow the unpacking. The tuple holds the old values in the swapped order, so handing them out one each puts each value in the other name.
temp variable was for. The reason x = y then y = x fails is that the first line destroys x before the second can read it. Packing the pair takes a copy of both before anything is assigned — so the tuple is the third box, made and thrown away in one line.x = 10, y = 20 x = y -> x is 20, y is 20 (the 10 is gone) y = x -> y is 20 (there is nothing left to swap)
Two things follow from that, and both are worth knowing. The swap works for any number of names — a, b, c = c, a, b rotates three values in one line. And it works with list positions too, which is exactly the swap the reverse-in-place program did the long way:
# rotating three values, and swapping two items of a list
a = 1
b = 2
c = 3
a, b, c = c, a, b
print(a, b, c)
numbers = [10, 20, 30, 40, 50]
numbers[0], numbers[4] = numbers[4], numbers[0]
print(numbers)3 1 2 [50, 20, 30, 40, 10]
temp version anyway. This one is Python's, and a question that says “swap two numbers without using a third variable” is asking for it. A question that says “write an algorithm to swap two numbers” wants the three-line version with temp, because that is the one every other language needs.4One thing to watch: a stray comma packs
Because a comma is all it takes, a comma in the wrong place quietly makes a tuple where you wanted a value:
# a trailing comma, and what it does
total = 100
answer = total,
print(answer)
print(answer + 5)(100,)
Traceback (most recent call last):
File "stray_comma.py", line 7, in <module>
print(answer + 5)
~~~~~~~^~~
TypeError: can only concatenate tuple (not "int") to tupleThe message is worth reading carefully — it says tuple, which is the clue. Whenever a value you expected to be a number turns out to be a tuple of one, look for a comma at the end of the line that made it.
5Recap
point = 3, 7 builds a tuple. Brackets are optional — the comma is what does it, which is why 5, is a tuple and (5) is not.
Always has, since the first variables lesson. In a swap that means both old values are packed before either name is changed.
It holds a copy of both values while the assignment happens, which is exactly the job the third box was doing.
a, b, c = c, a, b rotates three. numbers[0], numbers[4] = numbers[4], numbers[0] swaps two items in place.
point = 3, 7 with no brackets. What type is point?
In x, y = y, x, what happens first?
answer = total, and then answer + 5 raises TypeError. Why?