Словарь Python: есть ключи() и values ​​() всегда одинаковый порядок?

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

Например:

>>> 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-loop всегда будет печатать True? Я не мог найти документацию, подтверждающую это.

Ответ 1

Найдено следующее:

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

for key, value in myDictionary.iteritems():
    print key, value

Ответ 7

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

k, v = zip(*d.iteritems())

Ответ 8

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

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

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]

Ответ 9

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

zip(d.keys(), d.values())

Так как порядок доступа остается тем же, хотя и не предсказуемым, это всегда будет возвращать тот же (ключ, значение) кортеж.