Перебор словарей с использованием циклов 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
или для обоих вместе .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)
Но для академических целей пример вопроса вполне подойдет.