Probably people
is a dictionary that maps tuples to other data:
>>> people = {("Obama", "Barack"):"USA", ("Roussef", "Dilma"):"BRA"}
>>> for last, first in people:
... print(last, first, people[last, first])
...
Roussef Dilma BRA
Obama Barack USA
If you are not familiar with tuples, the data type tuple
is just like a list, only immutable:
x = (10, 20, 30)
y = ()
z = (10,) # Aqui a vírgula é obrigatória, pra não se confundir com 10 entre parênteses
What makes things confusing is that the Python syntax accepts that you omit the parentheses if the tuple has 2 or more elements:
x = 10, 20, 30
That is, people[last, first]
is the same as people[(last, first)]
.
As for the data type people
, I figured it was a dict
because it's the only way this code makes sense. Arrays only allow indexing by number, not by tuples, so people
is not an array. Since a dict
allows tuples as keys, and as for
applied to a dictionary iterates over its keys, I imagined this to be the right data structure.
By the way, you can iterate over lists / tuples and their indexes or dictionaries and their values using enumerate
and items
, respectively:
>>> lista = [10, 20, 30]
>>> for indice, valor in enumerate(lista):
... print(indice, valor)
...
0 10
1 20
2 30
>>> person = {"Name": "Barack", "Surname": "Obama"}
>>> for chave, valor in person.items():
... print(chave, valor)
...
Name Barack
Surname Obama
These examples work because both enumerate
and items
return tuples. In this way, you can do a destructuring assignment (or destructuring bind ) of your values to a set of other variables:
x, y = 10, 20 # destructuring assignment: x recebe 10, y recebe 20
for x, y in [(10, 20), (30, 40)]: # destructuring bind: para cada tupla t da lista
... # x recebe t[0] e y recebe t[1]
Finally, we came to your "strange" error message: "too many values to unpack" means that you attempted a destructuring bing where there were more right than left:
>>> x, y, z = 10, 20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack
>>> x, y, z = 10, 20, 30 # OK
>>> x, y, z = 10, 20, 30, 40
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
And how did this happen? Simple, in their dict
the keys were strings, and strings also accept destructuring bind !
>>> x, y, z, u, v = "teste"
>>> print(x, y, z)
t e s
>>> print(u, v)
t e
Since Name
has 4 letters, but the tuple (last, first)
only has 2 elements, Python has nowhere to put the last two letters. Curiously, if your keys had 2 letters, the error message would be different:
>>> person = {"FN": "Barack", "SN": "Obama"}
>>> for last, first in person:
... print(person[last, first])
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyError: ('F', 'N')
In this case it would be assigning the last
the value "F"
and the first
the value "N"
. And of course, since the dictionary keys are strings and not tuples, the ("F", "N")
key was not found in the dictionary ...