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

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

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

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

+2679
20 июл. '10 в 22:27
источник поделиться
15 ответов

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() будет работать как для 2, так и для 3, но в 2 она вернет список пар слов (key, value), которые не будут отражать изменения в dict, которые происходят после вызова items(). Если вы хотите выполнить 2.x в 3.x, вы можете вызвать list(d.items()).

+4739
20 июл. '10 в 22:29
источник

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

В случае словарей это реализовано на уровне 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().

В Python 3 dict.iterkeys(), dict.itervalues() и dict.iteritems() больше не поддерживаются. dict.keys() используйте dict.keys(), dict.values() и dict.items().

+385
20 июл. '10 в 23:52
источник

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

Изменить: (Это больше не выполняется в 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))
+182
21 июл. '10 в 1:27
источник

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)
+72
20 июл. '10 в 23:49
источник

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

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

+49
20 июл. '10 в 22:29
источник

Это очень распространенная идиома. in является оператором. Информацию о том, когда использовать for key in dict и когда он должен использоваться for key in dict.keys() см. В статье David for key in dict.keys() Python (заархивированная копия).

+26
20 июл. '10 в 22:42
источник

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

for key,val in d.items():
    print key, 'is the key for ', val
+15
14 янв. '17 в 14:42
источник

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

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

Обратите внимание, что круглые скобки вокруг ключа, значение важно, без круглых скобок вы получаете значение ValueError "Недостаточно значений для распаковки".

+13
25 мая '17 в 13:42
источник

Как бы то ни было, на данный момент оба python 2.6 и 2.7, а также 3.x в моей коробке хорошо работают с items():

z = {0: 'a', 1: 'b'}
for k, v in z.items(): print(v, k)
+13
05 янв. '19 в 18:08
источник

Итерация над словарями с использованием циклов '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__ объекта (в данном случае словаря), который возвращает итератор (в данном случае объект-ключ):

>>> 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']

Возврат к dicts

Мы видели, как во многих контекстах итерации повторялись. То, что мы видели, это то, что в любой момент, когда мы перебираем диктофон, мы получаем ключи. Вернемся к исходному примеру:

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)

Но для академических целей пример вопроса просто замечательный.

+12
21 июн. '17 в 2:51
источник

Вы можете проверить реализацию CPython dicttype на GitHub. Это сигнатура метода, который реализует итератор dict:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c

+7
03 нояб. '17 в 5:16
источник

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

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

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

+2
31 дек. '15 в 18:39
источник

Для ключа в my_dict фактически равно для ключа в my_dict.keys(). Поэтому, если вы хотите получить значения dict, вы можете попробовать два метода.

Один:

for value in my_dict.values():
    print(value)

Два:

for key in my_dict:
    print(my_dict[key])
+1
11 мар. '19 в 19:38
источник

Печать предложения для длинных значений
Если у вас есть длинные строки в значениях, вот быстрый способ распечатать это в (более?) Читаемом формате:
for key, value in my_dictionary.iteritems(): print(key) print("---------") print(value) print("\n")

+1
13 мая '19 в 20:56
источник

Python 2

Диктонарии - это очень важный tpo Python, который также очень прост в использовании. Для повторения каждой клавиши словаря вы просто используете "для k в d" или "для ключа в d" или любую переменную вместо k или ключа, как в моих примерах. Это потому, что по умолчанию вы можете перебирать ключи словаря именно так. для доступа к значениям ключей, которые вы нам только выбрали d [k] или d [key] или d [nameofvariable], в зависимости от переменной, которую вы использовали в цикле, для итерации ключей.

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

Python 3.6

вы также можете сделать что-то вроде этого:

d = {'x': 1, 'y': 2, 'z': 3} 
for k,v in d.items():
    print(k,":",v)

Выход

x : 1
y : 2
z : 3
0
26 окт. '17 в 4:41
источник

Посмотрите другие вопросы по меткам или Задайте вопрос