Перебор словарей с использованием циклов for

avatar
TopChef
20 июля 2010 в 22:27
4860893
15
3653

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

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

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

Источник
Raksha Saini
10 января 2021 в 04:26
0

Как мы знаем, в Словаре Python как набор пар ключ: значение с требованием, чтобы ключи были уникальными (в пределах одного словаря). Пара скобок создает пустой словарь: {}. Помещение разделенного запятыми списка пар ключ: значение в фигурные скобки добавляет в словарь начальные пары ключ: значение. Нет, ключ - это не особое слово в Python. Здесь ключ - это просто имя переменной.

Charlie Parker
16 марта 2021 в 22:11
1

вы пробовали: for key, value in d.items():?

Ответы (15)

avatar
sberry
20 июля 2010 в 22:29
6072

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

for key in d:

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

Для Python 3.x:

for key, value in d.items():

Для Python 2.x:

for key, value in d.iteritems():

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

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

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

quiet_penguin
28 июля 2017 в 09:43
208

Добавление пропущенной причины не обращаться к значению, например: d [key] внутри цикла for, приводит к повторному хешированию ключа (для получения значения). Когда словарь большой, этот дополнительный хеш добавляется к общему времени. Это обсуждается в техническом докладе Раймонда Хеттингера youtube.com/watch?v=anrOzOapJ2E

yugr
25 августа 2018 в 09:06
36

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

JoeyC
8 ноября 2018 в 04:45
6

@HarisankarKrishnaSwamy какая альтернатива?

Ikbel benab
6 мая 2019 в 08:52
0

при использовании метода items() значения в словаре будут переключаться, поэтому использование d[key] будет более точным.

Russell Lego
11 июня 2019 в 22:25
0

это на самом деле не работает In [10]: d Out[10]: {'id': [1, 2, 3], 'name': ['russell', 'priya', 'ravi']} In [11]: for key, value in d.iteritems(): ...: print key ...: print value ...: name ['russell', 'priya', 'ravi'] id [1, 2, 3]

Geza Turi
13 июля 2019 в 15:48
10

@yugr Почему ты так говоришь? В документах говорится: Keys and values are iterated over in insertion order. [docs.python.org/3/library/…

yugr
13 июля 2019 в 20:49
3

@GezaTuri Только начиная с Python 3.6 (ходили слухи, что эта «функция» может быть снова удалена в будущих версиях).

Aimery
9 сентября 2019 в 14:54
21

@yugr Начиная с Python 3.7 словари упорядочены по вставке, и это особенность языка. См. Coderhelper.com/a/39980744/9428564.

yugr
9 сентября 2019 в 15:44
1

@Aimery Это здорово, может быть, через 10 лет его можно будет использовать в переносимом коде. Поддерживают ли это IronPython и Pypy?

mrT
31 января 2020 в 15:45
0

Как получить ключ для заданного значения с помощью условия, например, если бы у меня было несколько домашних животных, и я хотел бы проверить, какое животное соответствует числу 4 dict = {'cats' : 5, 'dogs' : 4, 'fish' : 7}, как бы вы использовали условие для получения ключевых собак 'от заданного значения, например 4?

Mina Michael
22 июня 2021 в 01:50
0

Также в Python 3.x есть for value in d.values() :

avatar
theAccountant.py
17 января 2022 в 21:40
0

Словарь в Python — это набор пар ключ-значение. Каждый ключ связан со значением, и вы можете использовать ключ для доступа к значению, связанному с этим ключом. Значением ключа может быть число, строка, список или даже другой словарь. В этом случае представляйте каждую «пару ключ-значение» отдельной строкой в ​​таблице: d — это ваша таблица с двумя столбцами. ключ - это первый столбец, ключ [значение] - ваш второй столбец. Цикл for — это стандартный способ перебора таблицы.

avatar
Gowdham V
15 января 2022 в 18:31
3

Для перебора словарей можно использовать приведенный ниже код.

dictionary= {1:"a", 2:"b", 3:"c"}

#To iterate over the keys
for key in dictionary.keys():
    print(key)

#To Iterate over the values
for value in dictionary.values():
    print(value)

#To Iterate both the keys and values
for key, value in dictionary.items():
    print(key,'\t', value)
avatar
Rohit_VE
19 мая 2021 в 07:55
-1

Давайте сразу к делу. Если слово key - это просто переменная, как вы упомянули, то главное отметить, что когда вы запускаете 'FOR LOOP' по словарю, он проходит только через 'keys' и игнорирует 'values' .

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

попробуйте это:

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

, но если вы используете такую ​​функцию, как:

d = {'x': 1, 'y': 2, 'z': 3}
print(d.keys())

в приведенном выше случае «ключи» просто не переменная, это функция.

avatar
Mister Verleg
9 сентября 2020 в 14:41
6

Если вы ищете наглядный и наглядный пример:

cat  = {'name': 'Snowy', 'color': 'White' ,'age': 14}
for key , value in cat.items():
   print(key, ': ', value)

Результат:

name:  Snowy
color:  White
age:  14
avatar
Amar Kumar
18 апреля 2020 в 20:56
8

Будет напечатан вывод в отсортированном порядке по значениям в порядке возрастания.

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

def by_value(item):
    return item[1]

for key, value in sorted(d.items(), key=by_value):
    print(key, '->', value)

Вывод:

y -> 1
z -> 2
x -> 3
Joe Ferndz
29 декабря 2020 в 23:25
1

Я не думаю, что это был вопрос. Вопрос был о ключе и почему python берет ключи из словаря без опции .items () или .keys ().

avatar
Ankur Agarwal
3 ноября 2017 в 05:16
12

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

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

CPython dictobject.c

avatar
Aaron Hall
21 июня 2017 в 02:51
27

Перебор словарей с использованием циклов 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']

Возвращение к dicts

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

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

Если мы хотим перебрать значения, нам нужно использовать метод dicts .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)

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

avatar
jdhao
25 мая 2017 в 13:42
27

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

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

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

jorijnsmit
13 апреля 2020 в 09:19
2

Как это относится к вопросу?

Neuron
25 февраля 2021 в 12:55
0

Мне не нравится использование здесь i. Это означает, что значения перебираются в последовательном порядке, что не так.

avatar
Neil Chowdhury o_O
31 декабря 2015 в 18:39
8

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

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

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

Martijn Pieters
13 октября 2020 в 14:28
1

Почему «лучше» использовать my_dict.keys() вместо итерации непосредственно по словарю? Итерация по словарю четко документируется как выдача ключей. Похоже, вы имели в виду Python 2, когда ответили на это, потому что в Python 3 for key in my_dict.keys() будет по-прежнему возникать та же проблема с изменением размера словаря во время итерации .

avatar
John La Rooy
21 июля 2010 в 01:27
242

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

(Это больше не работает в Python 3.6 , но обратите внимание, что это не гарантирует поведение5113082161405.) <

>>> 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))

Gregory Arenius
18 июля 2018 в 16:30
20

Из примечаний к выпуску Python 3.7: «Сохранение порядка вставки объектов dict теперь является официальной частью спецификации языка Python».

avatar
ars
20 июля 2010 в 23:52
495

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

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

avatar
ssoler
20 июля 2010 в 23:49
108

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

Для Python2.X :

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

x corresponds to 1
y corresponds to 2
z corresponds to 3

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

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)
avatar
chryss
20 июля 2010 в 22:42
39

Это очень распространенная идиома зацикливания. in - оператор. Чтобы узнать, когда использовать for key in dict, а когда он должен быть for key in dict.keys(), см. статью Дэвида Гуджера «Идиоматический Python» (архивная копия).

Wolf
19 мая 2016 в 12:17
0

Когда я читал эти разделы о in, операторская часть - , где вы проверяете наличие. Может быть, лучше удалить эту информацию in is an operator .

avatar
Alexander Gessler
20 июля 2010 в 22:29
72

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

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

Andreas Fester
26 марта 2015 в 11:38
45

Обратите внимание, что для Python 3 это items() вместо iteritems()