Почему вы должны вызывать .iteritems () при переборе словаря в python? - PullRequest
129 голосов
/ 19 сентября 2010

Почему вы должны вызывать iteritems() для перебора пар ключ-значение в словаре? т.е.

dic = {'one':'1', 'two':'2'}
for k, v in dic.iteritems():
    print k, v

Почему это не стандартное поведение итерации по словарю

for k, v in dic:
    print k, v

Ответы [ 2 ]

170 голосов
/ 19 сентября 2010

Для каждого контейнера C Python ожидается, что

for item in C:
    assert item in C

пройдет просто отлично - неужели вы не удивитесь, если одно чувство in (предложение цикла) будет иметь совершенно другое значение, чем другое (проверка присутствия)? Я уверен, что будет! Это естественно работает таким образом для списков, множеств, кортежей, ...

Итак, когда C является словарем, если бы in должен был давать кортежи ключ / значение в цикле for, то, по принципу наименьшего удивления, in также должен был бы принять такой кортеж в качестве левого операнда в проверке содержимого.

Насколько это было бы полезно? Довольно бесполезно, фактически делая if (key, value) in C синонимом для if C.get(key) == value - это проверка, которую, я считаю, я мог выполнить или хотел выполнить в 100 раз реже, чем то, что if k in C на самом деле означает, проверяя наличие ключа только и полностью игнорируя значение.

С другой стороны, желание зацикливаться только на клавишах довольно распространено, например ::1010

for k in thedict:
    thedict[k] += 1

значение также не поможет, особенно:

for k, v in thedict.items():
    thedict[k] = v + 1

на самом деле несколько менее ясно и менее сжато. (Обратите внимание, что items было первоначальным написанием «правильных» методов, используемых для получения пар ключ / значение: к сожалению, это было в те времена, когда такие средства доступа возвращали целые списки, поэтому для поддержки «простой итерации» альтернативное написание имело будет представлен, и iteritems это было - в Python 3, где ограничения обратной совместимости с предыдущими версиями Python были значительно ослаблены, он снова стал items).

9 голосов
/ 19 сентября 2010

Мое предположение: Использование полного кортежа было бы более интуитивно понятным для циклов, но, возможно, менее для тестирования членства с использованием in.

if key in counts:
    counts[key] += 1
else:
    counts[key] = 1

Этот код не будет работать, если вам нужно будет указать ключ и значение для in. Я с трудом представляю себе случай использования, в котором вы бы проверили, есть ли оба значения ключа И в словаре. Гораздо более естественно проверять только ключи.

# When would you ever write a condition like this?
if (key, value) in dict:

Теперь нет необходимости, чтобы оператор in и for ... in работали над одними и теми же элементами. По реализации это разные операции (__contains__ против __iter__). Но это маленькое несоответствие может быть несколько запутанным и, ну, в общем, непоследовательным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...