Словарь Python: ключи () и значения () всегда одинакового порядка?

312

Похоже, что списки, возвращаемые keys()и values()методы словаря, всегда являются отображением 1: 1 (при условии, что словарь не изменяется между вызовами 2 методов).

Например:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

Если вы не измените словарь между вызовом keys()и вызовом values(), неправильно ли считать, что приведенный выше цикл for всегда будет печатать True? Я не смог найти никаких документов, подтверждающих это.

Джейсон Кун
источник
1
В CPython 3.7 (и выше, по-видимому) вы можете полагаться на порядок итераций словаря, соответствующего порядку вставки. mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen
@BallpointBen это в CPython 3.6 и выше и во всех других реализациях Python, начиная с Python 3.7
Борис

Ответы:

353

Нашел это:

Если items(), keys(), values(), iteritems(), iterkeys(), и itervalues()называются без промежуточных модификаций в словарь, списки будут напрямую соответствовать.

На 2.x документации и 3.x документации .

nosklo
источник
5
по-видимому, утверждение в документации 3.x яснее: «порядок предметов будет напрямую соответствовать»
Шаохуа Ли,
4
Этот текст отсутствует в документации 3.7. Я могу только предположить, что это потому, что «Dict сохраняет порядок вставки» в 3.7: mail.python.org/pipermail/python-dev/2017-De
December/
80

Да, то, что вы заметили, действительно является гарантированным свойством - keys (), values ​​() и items () возвращают списки в согласованном порядке, если dict не изменяется. iterkeys () & c также выполняет итерацию в том же порядке, что и соответствующие списки.

Алекс Мартелли
источник
1
Однако, в случае , если список будет изменен, панды dataframeпредлагает альтернативу , где элементы могут быть обновлены или удалены, а также порядок и расположения индексов из элементов в Словаре-подобной структуры остаются неизменными.
Вилле
48

Да, это гарантировано в Python 2.x :

Если представления ключей, значений и элементов повторяются без внесения изменений в словарь, порядок элементов будет напрямую соответствовать.

Bjorn
источник
6

Хорошие ссылки на документы. Вот как вы можете гарантировать заказ независимо от документации / реализации:

k, v = zip(*d.iteritems())
Сасса Н.Ф.
источник
1
В python3.x используйте dict.items ()
Good Will
4

Согласно http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects , методы dict keys (), values ​​() и items () будут возвращать соответствующие итераторы, чьи порядки соответствовать. Тем не менее, я не могу найти ссылку на официальную документацию для Python 2.x по той же причине.

Так что, насколько я могу судить, ответ да, но только в Python 3.0+

Сикора
источник
4

Что бы это ни стоило, некоторый интенсивно используемый производственный код, который я написал, основан на этом предположении, и у меня никогда не было проблем с ним. Я знаю, что это не делает это правда :-)

Если вы не хотите рисковать, я бы использовал iteritems (), если вы можете.

for key, value in myDictionary.iteritems():
    print key, value
Коен Бок
источник
-2

Я не был удовлетворен этими ответами, так как хотел, чтобы экспортированные значения имели одинаковый порядок, даже при использовании разных диктов.

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

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
jlansey
источник