Ответ 1
Найдено следующее:
Если
items()
,keys()
,values()
,iteritems()
,iterkeys()
иitervalues()
вызываются без промежуточных модификаций словарь, списки будут напрямую соответствует.
Похоже, что списки, возвращаемые методами 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? Я не мог найти документацию, подтверждающую это.
Найдено следующее:
Если
items()
,keys()
,values()
,iteritems()
,iterkeys()
иitervalues()
вызываются без промежуточных модификаций словарь, списки будут напрямую соответствует.
Да, то, что вы наблюдали, действительно является гарантированным свойством - keys(), values () и items() списками возврата в конгруэнтном порядке, если dict не изменяется. iterkeys() & c также выполняют итерацию в том же порядке, что и соответствующие списки.
Да, это гарантировано в python 2.x:
Если ключи, значения и представления элементов повторяются без промежуточных изменения в словаре, порядок элементов будет напрямую соответствует.
Согласно http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects, методы dict keys(), values () и items() будут возвращать соответствующие итераторы, чьи порядки соответствовать. Тем не менее, я не могу найти ссылку на официальную документацию для Python 2.x по той же причине.
Так что, насколько я могу судить, ответ - да, но только в Python 3. 0+
Для чего это стоит, какой-то тяжелый использованный код производства, который я написал, основан на этом предположении, и у меня никогда не было проблемы с ним. Я знаю, что это не правда, хотя: -)
Если вы не хотите рисковать, я бы использовал iteritems(), если вы можете.
for key, value in myDictionary.iteritems():
print key, value
Да. Начиная с CPython 3.6, словари возвращают элементы в том порядке, в котором вы их вставили.
Проигнорируйте часть, которая говорит, что это деталь реализации. Это поведение гарантировано в CPython 3.6 и требуется для всех других реализаций Python, начиная с Python 3.7.
Хорошие ссылки на документы. Вот как вы можете гарантировать заказ независимо от документации/реализации:
k, v = zip(*d.iteritems())
Я не был удовлетворен этими ответами, так как я хотел, чтобы экспортированные значения имели одинаковый порядок даже при использовании разных 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]
Как уже указывалось, да, многие практические применения будут обеими обеими.
zip(d.keys(), d.values())
Так как порядок доступа остается тем же, хотя и не предсказуемым, это всегда будет возвращать тот же (ключ, значение) кортеж.