шагом - цикл for python




Итерация над словарями с использованием циклов 'for' (8)

Итерация над словарями с использованием циклов 'for'

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

Как Python распознает, что ему нужно только прочитать ключ из словаря? Является ли ключевым слово в Python? Или это просто переменная?

Это не только петли. Важным словом здесь является «итерация».

Словарь - это отображение ключей к значениям:

d = {'x': 1, 'y': 2, 'z': 3} 

Каждый раз, когда мы перебираем его, мы перебираем ключи. key именем переменной предназначен только для описания, и он вполне подходит для этой цели.

Это происходит в понимании списка:

>>> [k for k in d]
['x', 'y', 'z']

Это происходит, когда мы передаем словарь для отображения (или любого другого объекта типа коллекции):

>>> list(d)
['x', 'y', 'z']

То, как выполняется __iter__ 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)

Но в академических целях пример вопроса в порядке.

Я немного озадачен следующим кодом:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

То, что я не понимаю, является key частью. Как Python распознает, что ему нужно только прочитать ключ из словаря? Является ли key слово в Python? Или это просто переменная?


Вы можете использовать это:

for key,val in d.items():
    print key, 'is the key for ', val

Итерация через dict итерации осуществляется через его ключи в определенном порядке, как вы можете видеть здесь:

Edit: (Это уже не так в Python3.6 , но обратите внимание, что это еще не гарантированное поведение)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

Для вашего примера лучше использовать dict.items() :

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

Это дает вам список кортежей. Когда вы перебираете их так, каждый кортеж автоматически распаковывается в k и v :

for k,v in d.items():
    print(k, 'corresponds to', v)

Использование k и v качестве имен переменных, когда цикл над dict довольно распространен, если тело цикла - всего несколько строк. Для более сложных циклов может быть хорошей идеей использовать более описательные имена:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

Это хорошая идея, чтобы привыкнуть использовать строки форматирования:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

Когда вы повторяете словари, используя for .. in .. -syntax, он всегда выполняет итерации по клавишам (значения доступны с помощью dictionary[key] ).

Чтобы перебрать пары ключ-значение, используйте for k,v in s.iteritems() .


Чтобы перебирать ключи, это медленнее, но лучше использовать my_dict.keys() . Если вы попытались сделать что-то вроде этого:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

это создаст ошибку времени выполнения, потому что вы меняете ключи во время работы программы. Если вы абсолютно настроены на сокращение времени, используйте for key in my_dict , но вы были предупреждены;).


Это не тот ключ, это специальное слово, но словари реализуют протокол итератора. Вы можете сделать это в своем классе, например, см. Этот вопрос о том, как создавать итераторы классов.

В словарях он реализован на уровне C. Подробности доступны в PEP 234 . В частности, раздел «Итераторы словарей»:

  • Словари реализуют слот tp_iter, который возвращает эффективный итератор, который выполняет итерацию по клавишам словаря. [...] Это означает, что мы можем написать

    for k in dict: ...
    

    что эквивалентно, но намного быстрее, чем

    for k in dict.keys(): ...
    

    пока ограничение на модификации словаря (ни по циклу, ни по другому потоку) не будет нарушено.

  • Добавьте методы в словари, которые явным образом возвращают разные типы итераторов:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    Это означает, что for x in dict for x in dict.iterkeys() .


key - просто переменная.

Для Python2.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... или лучше,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Для Python3.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

key - это просто имя переменной.

for key in d:

будет просто перебирать ключи в словаре, а не ключи и значения. Чтобы перебрать оба ключа и значения, вы можете использовать следующее:

Для Python 2.x:

for key, value in d.iteritems():

Для Python 3.x:

for key, value in d.items():

Чтобы проверить себя, измените слово key на poop .

Для Python 3.x, iteritems() заменен просто items() , который возвращает представление типа, поддерживаемое dict, как iteritems() но еще лучше. Это также доступно в 2.7 как viewitems() .

items() операции items() будут работать как для 2, так и для 3, но в 2 он вернет список пар слов словаря (key, value) , который не будет отражать изменения в dict, которые происходят после вызова items() . Если вы хотите 2.x поведение в 3.x, вы можете вызвать list(d.items()) .





dictionary