Порядок ключей в словарях

103

Код:

d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()

print l

Это печатает ['a', 'c', 'b']. Я не уверен, как метод keys()определяет порядок ключевых слов в l . Однако я хотел бы иметь возможность извлекать ключевые слова в «правильном» порядке. Правильный порядок, конечно, создаст список ['a', 'b', 'c'].

прямоугольник
источник
4
Если словари Python похожи на большинство, то на самом деле это хеш-таблицы. Среди прочего, это означает, что порядок ключей не гарантируется и даже не указывается. В частности, он не запомнил порядок добавления ключей.
cHao
4
@cHao: По сути, это означает, что ваша программа будет недетерминированной, если вы перебираете элементы в словаре?
HelloGoodbye
5
@HelloGoodbye: я бы не пошел так далеко; там все еще очень предсказуемое поведение. На каждой полной итерации отображается ровно одно значение из каждой пары ключ / значение. И на большинстве языков вы даже будете видеть их каждый раз в одном и том же порядке. Однако, если документы не гарантируют конкретный порядок, вы не должны рассчитывать на то, что это тот порядок, который вам нужен. (Некоторые языки (например, Perl) на самом деле немного рандомизируют порядок - якобы по соображениям безопасности, но я думаю, что это действительно просто для того, чтобы избавиться от привычки полагаться на неопределенное поведение. :) Я не думаю, что Python вполне подходит это зло, но э ...)
cHao
1
Порядок будет таким же, если диктант не был изменен. Из руководства: «Если items (), keys (), values ​​(), iteritems (), iterkeys () и itervalues ​​() вызываются без каких-либо промежуточных изменений в словаре, списки будут напрямую соответствовать. Это позволяет создавать пар (значение, ключ) с помощью zip (): pair = zip (d.values ​​(), d.keys ()) ".
steveayre
2
@sfranky Я думаю, что стивейр имел в виду то, что порядок совпадает между тем, что вы получаете, используя различные упомянутые методы, а не то же самое, что и порядок, в котором были написаны элементы.
bli

Ответы:

79

Вы можете использовать OrderedDict (требуется Python 2.7) или выше.

Также обратите внимание, что OrderedDict({'a': 1, 'b':2, 'c':3})это не сработает, так как dictвы создаете с {...}уже забыли порядок элементов. Вместо этого вы хотите использовать OrderedDict([('a', 1), ('b', 2), ('c', 3)]).

Как упоминалось в документации, для версий ниже Python 2.7 вы можете использовать этот рецепт.

Абхинав Гупта
источник
18
Имейте в виду, что порядок OrderedDict - это порядок вставки ; ключи появятся только в алфавитном порядке, если вы вставили их таким образом.
Хью Ботвелл,
это то, что он показал в качестве упрощенного примера; оно может иметь или не иметь никакого отношения к тому, как он на самом деле планирует его использовать. Я ранее встречал людей, которые ожидали, что OrderedDict вернет произвольные вставки в отсортированном порядке, и поэтому я чувствовал, что должен указать на это.
Хью Ботвелл,
124

Python 3.7+

В Python 3.7.0 сохранение порядка вставки dictобъектов было объявлено официальной частью спецификации языка Python. Следовательно, вы можете на это положиться.

Python 3.6 (CPython)

Начиная с Python 3.6, для реализации Python в CPython словари по умолчанию поддерживают порядок вставки . Однако это считается деталью реализации; вы все равно должны использовать, collections.OrderedDictесли хотите, чтобы порядок вставки гарантировался в других реализациях Python.

Python> = 2.7 и <3.6

Используйте collections.OrderedDictкласс, когда вам нужен, dictкоторый запоминает порядок вставленных элементов.

Евгений Ярмаш
источник
51
>>> print sorted(d.keys())
['a', 'b', 'c']

Используйте функцию сортировки , которая сортирует переданный итерируемый объект.

.keys()Метод возвращает ключи в произвольном порядке.

Майк Льюис
источник
12
Это не сработает, если вам нужен исходный порядок, и он не был отсортирован.
Саймон
13

Из http://docs.python.org/tutorial/datastructures.html :

«Метод keys () объекта словаря возвращает список всех ключей, используемых в словаре, в произвольном порядке (если вы хотите его отсортировать, просто примените к нему функцию sorted ())».


источник
12

Просто отсортируйте список, когда захотите его использовать.

l = sorted(d.keys())
Нарисовался
источник
1

Хотя порядок не имеет значения, поскольку словарь - это hashmap. Это зависит от порядка, в котором он вставлен:

s = 'abbc'
a = 'cbab'

def load_dict(s):
    dict_tmp = {}
    for ch in s:
        if ch in dict_tmp.keys():
            dict_tmp[ch]+=1
        else:
            dict_tmp[ch] = 1
    return dict_tmp

dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))

вывод:
для строки abbc ключи - dict_keys (['a', 'b', 'c']),
для строки cbab ключи - dict_keys (['c', 'b', 'a'])

Зехай
источник
1
Словарь в Python является вставка заказывается только с версией 3.6 + проверить это
Crivella