Словарь Iterating - для dict vs for dict.items()

Когда мы перебираем словарь ниже, каждая итерация возвращает (правильно) ключ, пара значений

for key, value in dict.items():
    print "%s key has the value %s" % (key, value)

'some key' имеет значение 'some value' (повторяется, однако много раз имеется пара k, v)

Приведенное выше имеет смысл для меня, однако, если мы это сделаем:

for key in dict.items():
    print "%s key has the value %s" % (key, value)

("some key", "some value") имеет значение "some value" (левый кортеж будет перебирать каждую пару значений ключа, а правое значение останется только при первом значении в dict и повторить)

В результате получаем каждую пару k, v, возвращенную в первом %s (ключ), а второй %s (значение) не выполняет итерацию, он просто возвращает первое значение в dict для каждой итерации for цикл.

Я понимаю, что если вы повторяете только for key in dict, вы выполняете итерацию только по клавишам. Здесь, поскольку мы повторяем набор кортежей (используя dict.items()) только с ключом в цикле for, цикл должен выполняться в течение того же числа раз, что и первый пример, так как имеется столько ключей, сколько ключ, значение пар.

У меня возникли проблемы с пониманием того, почему python дает вам весь кортеж во втором примере для key.


Спасибо за помощь всем - я хотел бы добавить еще один вопрос в микс.

for a,a in dict.items():
    print a

Почему вышеприведенное значение выдает, а если я print a,a - очевидно, что оба значения печатаются дважды. Если бы я набрал for a,b, я бы повторял пары (key,value), поэтому я бы логично подумал, что теперь я повторяю пары (key,key) и поэтому печатаю ключ, а не значение. Извините за основные вопросы, которые просто играют в интерпретаторе и пытаются отобразить материал.

Ответы

Ответ 1

В первом примере используется что-то, известное как "распаковка кортежа", чтобы разбить то, что ДЕЙСТВИТЕЛЬНО такое же кортеж, что и в вашем отдельном примере, на две разные переменные.

Другими словами:

for key, value in dict.items():

Это только:

for keyvalue in dict.items():
    key, value = keyvalue[0], keyvalue[1]

Помните, что цикл for всегда выполняет итерацию по отдельным элементам итератора, которые вы ему даете. dict.items() возвращает подобный списку объект кортежей, поэтому каждый пробег в цикле for представляет собой новый кортеж, автоматически распаковываемый в key, value, если вы определяете его как таковой в цикле for.

Это может помочь подумать об этом так:

d = {'a':1, 'b':2, 'c':3}
list(d)          # ['a', 'b', 'c']             the keys
list(d.keys())   # ['a', 'b', 'c']             the keys
list(d.values()) # [1, 2, 3]                   the values
list(d.items())  # [('a',1), ('b',2), ('c',3)] a tuple of (key, value)

N.B. что единственная причина, по которой ваш код

for key in dict.items():
    print "%s key has value: %s" % (key, value)

Не выбрасывает NameError, потому что value уже определен из другого места вашего кода. Поскольку вы не определяете value где-либо в этом цикле for, в противном случае это создало бы исключение.

Ответ 2

Во втором примере, который вы указали, вы не присваиваете значение "значение":

Обратите внимание на небольшое изменение здесь:

for key in dict:  ##Removed call to items() because we just want the key, 
                  ##Not the key, value pair
    value = dict[key]  # Added this line
    print "%s key has the value %s (key, value)

Примечание:

Во втором примере вы можете теперь вызвать dict.keys() или просто dict (ссылка на словарь в цикле for вернет ему ключи). Вызов dict.items() будет конфессионально назначать key = (,) вероятно, не то, что вы хотите.