Перебор словарей с использованием циклов for
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
...
Как Python распознает, что ему нужно только прочитать ключ из словаря? Является ли ключ специальным словом в Python? Или это просто переменная?
Это не просто for
петли. Важное слово здесь - «повторение».
Словарь - это отображение ключей на значения:
d = {'x': 1, 'y': 2, 'z': 3}
Каждый раз, когда мы перебираем его, мы перебираем ключи. Имя переменной key
предназначено только для описания, и оно вполне подходит для этой цели.
Это происходит в понимании списка:
>>> [k for k in d]
['x', 'y', 'z']
Это происходит, когда мы передаем словарь в список (или любой другой объект типа коллекции):
>>> list(d)
['x', 'y', 'z']
Итерация Python заключается в том, что в контексте, где это необходимо, он вызывает __iter__
метод объекта (в данном случае словарь), который возвращает итератор (в данном случае, объект keyiterator):
>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>
Мы не должны сами использовать эти специальные методы, вместо этого использовать соответствующую встроенную функцию для вызова iter
:
>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
У итераторов есть __next__
метод, но мы вызываем его с помощью встроенной функции next
:
>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Когда итератор исчерпан, он повышается StopIteration
. Это то, как Python знает, как выйти из for
цикла, или из списка, или из выражения генератора, или из любого другого итеративного контекста. Когда итератор поднимается, StopIteration
он всегда поднимает его - если вы хотите повторить снова, вам нужен новый.
>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']
Возвращаясь к диктату
Мы видели повторения диктов во многих контекстах. Что мы видели, так это то, что каждый раз, когда мы перебираем слова, мы получаем ключи. Вернуться к исходному примеру:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
Если мы изменим имя переменной, мы все равно получим ключи. Давай попробуем:
>>> for each_key in d:
... print(each_key, '=>', d[each_key])
...
x => 1
y => 2
z => 3
Если мы хотим перебрать значения, нам нужно использовать .values
метод dicts или для обоих вместе .items
:
>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]
В приведенном примере было бы более эффективно перебирать элементы вроде этого:
for a_key, corresponding_value in d.items():
print(a_key, corresponding_value)
Но для академических целей пример вопроса просто отлично.