Итерация над словарями с использованием циклов 'for'
Я немного озадачен следующим кодом:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print key, 'corresponds to', d[key]
То, что я не понимаю, это часть key
. Как Python распознает, что ему нужно только прочитать ключ из словаря? Является ли key
специальным словом в Python? Или это просто переменная?
Ответы
Ответ 1
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())
.
Ответ 2
Это не тот ключ, это специальное слово, но то, что словари реализуют протокол итератора. Вы можете сделать это в своем классе, например, посмотреть этот вопрос о том, как создавать итераторы класса.
В случае словарей это реализовано на уровне 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()
.
Ответ 3
Итерация по 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))
Ответ 4
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)
Ответ 5
Когда вы перебираете словари, используя for.. in..
-syntax, он всегда перебирает ключи (значения доступны с помощью dictionary[key]
).
Чтобы перебрать пары ключ-значение, в Python 2 используйте for k,v in s.iteritems()
и в Python 3 for k,v in s.items()
.
Ответ 6
Это очень распространенная идиома. in
является оператором. Информацию о том, когда использовать for key in dict
и когда он должен использоваться for key in dict.keys()
см. В статье David for key in dict.keys()
Python (заархивированная копия).
Ответ 7
Вы можете использовать это:
for key,val in d.items():
print key, 'is the key for ', val
Ответ 8
У меня есть прецедент, когда я должен итерации через dict, чтобы получить ключ, пара значений, а также индекс, указывающий, где я. Вот как я это делаю:
d = {'x': 1, 'y': 2, 'z': 3}
for i, (key, value) in enumerate(d.items()):
print(i, key, value)
Обратите внимание, что круглые скобки вокруг ключа, значение важно, без круглых скобок вы получаете значение ValueError "Недостаточно значений для распаковки".
Ответ 9
Как бы то ни было, на данный момент оба python 2.6 и 2.7, а также 3.x в моей коробке хорошо работают с items()
:
z = {0: 'a', 1: 'b'}
for k, v in z.items(): print(v, k)
Ответ 10
Итерация над словарями с использованием циклов '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)
Но для академических целей пример вопроса просто замечательный.
Ответ 11
Вы можете проверить реализацию CPython dicttype
на GitHub. Это сигнатура метода, который реализует итератор dict:
_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
PyObject **pvalue, Py_hash_t *phash)
CPython dictobject.c
Ответ 12
Чтобы перебирать клавиши, это медленнее, но лучше использовать my_dict.keys()
. Если вы попытались сделать что-то вроде этого:
for key in my_dict:
my_dict[key+"-1"] = my_dict[key]-1
он создаст ошибку времени выполнения, потому что вы меняете ключи во время работы программы. Если вы абсолютно настроены на сокращение времени, используйте способ for key in my_dict
, но вы были предупреждены;).
Ответ 13
Для ключа в my_dict фактически равно для ключа в my_dict.keys(). Поэтому, если вы хотите получить значения dict, вы можете попробовать два метода.
Один:
for value in my_dict.values():
print(value)
Два:
for key in my_dict:
print(my_dict[key])
Ответ 14
Печать предложения для длинных значений
Если у вас есть длинные строки в значениях, вот быстрый способ распечатать это в (более?) Читаемом формате:
for key, value in my_dictionary.iteritems(): print(key) print("---------") print(value) print("\n")
Ответ 15
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