Tuples and sets
Two more structures. Each does one job that lists and dicts do badly.
Tuples: values that belong together
A tuple is a fixed group of values, written with parentheses. Use it when
a few values form one thing, like an item and its price, or a position as
(row, column).
pair = ("bread", 25)
print(pair[0])
print(pair[1])
print(len(pair))
Indexing and slicing work as for lists, but a tuple cannot be changed: no
append, no assigning to a position. That is the point. A tuple says "these
go together and this is the complete set".
The parentheses are optional when writing a tuple; it is the commas that
make it one. pair = "bread", 25 means the same thing. And tuple(...)
turns a list into a tuple, just as list(...) turns a tuple into a list.
Unpacking
A tuple's values can be pulled out into separate names in one line.
pair = ("bread", 25)
item, price = pair
print(item)
print(price)
This is also how a function returns two things, and it gives a one-line
swap, which you may remember doing with a temporary name in the Names
exercises. (min and max below pick the smallest and largest of a list;
the next page covers them properly.)
def cheapest_and_dearest(prices):
return min(prices), max(prices)
low, high = cheapest_and_dearest([40, 25, 2.5])
print(low, high)
a, b = "apple", "bread"
a, b = b, a
print(a, b)
Sets: no duplicates, fast membership
A set holds values with no order and no repeats. Build one with curly
braces, or from a list with set().
basket = ["apple", "bread", "apple", "milk", "apple"]
unique = set(basket)
print(unique)
print(len(unique))
Because a set has no order, the order it prints in can differ from the order you added things, and even from one run to the next. Adding a value already present does nothing. Sets are the natural answer to "have I seen this before?".
seen = set()
seen.add("apple")
seen.add("bread")
seen.add("apple")
print(seen)
print("apple" in seen)
print("milk" in seen)
Sets have no positions, so seen[0] is an error. To get an empty set write
set(); {} is an empty dictionary.
Combining sets
shop_a = {"apple", "bread", "milk"}
shop_b = {"bread", "milk", "eggs"}
print(shop_a & shop_b)
print(shop_a | shop_b)
print(shop_a - shop_b)
& is what both have, | is everything in either, - is what the first has
that the second does not.
Which structure?
| You need | Use |
|---|---|
| An ordered collection you will add to and change | list |
| A few values that form one thing, never changed | tuple |
| Lookup by a key you choose | dict |
| Uniqueness or fast "is it in there?" | set |
Try it
Split a pair
Each stock entry is a tuple (item, quantity). Write describe(entry) that
returns the text <quantity> x <item>.
describe(("bread", 3)) -> "3 x bread"
def describe(entry):
...
Unique items
Write unique_count(basket) that returns how many different items are
in the list basket.
unique_count(["apple", "bread", "apple", "milk", "apple"]) -> 3
unique_count([]) -> 0
def unique_count(basket):
...
In both shops
Two shops each have a list of items. Write in_both(a, b) that returns a
list of the items that appear in both, each item once, in any order.
in_both(["apple", "bread", "milk"], ["milk", "eggs", "apple"]) -> ["apple", "milk"] (or ["milk", "apple"])
in_both(["apple"], ["bread"]) -> []
def in_both(a, b):
...
Next: Built-in functions.