Я пытаюсь получить отсортированный словарь. Но порядок пунктов между mydict и orddict, похоже, не меняется.

from collections import OrderedDict

mydict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

orddict = OrderedDict(mydict)

print(mydict, orddict)

# print items in mydict:
print('mydict')
for k, v in mydict.items():
    print(k, v)

print('ordereddict')
# print items in ordered dictionary
for k, v in orddict.items():
    print(k, v)


# print the dictionary keys
# for key in mydict.keys():
#     print(key)


#  print the dictionary values
# for value in mydict.values():
#     print(value)
19
liv2hak 16 Дек 2015 в 09:06

5 ответов

Лучший ответ

OrderedDict сохраняет элементы порядка, которые были вставлены:

>>> od = OrderedDict()
>>> od['c'] = 1
>>> od['b'] = 2
>>> od['a'] = 3
>>> od.items()
[('c', 1), ('b', 2), ('a', 3)]
>>> d = {}
>>> d['c'] = 1
>>> d['b'] = 2
>>> d['a'] = 3
>>> d.items()
[('a', 3), ('c', 1), ('b', 2)]

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

Если вы хотите «отсортировать» словарь, вы, вероятно, хотите

>>> sorted(d.items())
[('a', 1), ('b', 2), ('c', 3)]
12
Brian Malehorn 16 Дек 2015 в 06:13

Добавляя к ответу Брайана, OrderedDict действительно здорово. Вот почему:

  • Вы можете использовать его как простой dict объект, поскольку он поддерживает тестирование на равенство с другими Mapping объектами, такими как collection.counter.

  • OrderedDict сохраняет порядок вставки, как объяснил Брайан. В дополнение к этому у него есть метод popitem, который возвращает (ключ, значение) пары в порядке LIFO. Таким образом, вы также можете использовать его как сопоставленный «стек».

Вы получаете не только все возможности dict, но и некоторые интересные трюки.

3
xssChauhan 16 Дек 2015 в 06:45

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

Так что сортируется только по порядку добавления в диктант

Вы можете построить заказ OrderedDict по ключу, как следует,

orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[0]))

Или просто как @ShadowRanger, упомянутый в комментарии

orddict = OrderedDict(sorted(d.items()))

Если вы хотите заказать по стоимости,

orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[1]))

Дополнительную информацию см. В 8.3.5.1. Примеры и рецепты OrderedDict

3
neo 16 Дек 2015 в 06:17

Из документации для OrderedDict (выделено мое):

Некоторые отличия от dict все еще остаются:

  • Обычный dict был разработан, чтобы очень хорошо отображать операции . Порядок вставки отслеживания был вторичным.

  • OrderedDict был разработан, чтобы хорошо переупорядочивать операции. Эффективность пространства, скорость итерации и производительность обновления операции были вторичными.

  • Алгоритмически, OrderedDict может обрабатывать частые изменения порядка операции лучше, чем dict. Это делает его пригодным для отслеживания недавние обращения (например, в кэш LRU).

  • Операция равенства для OrderedDict проверяет на соответствие порядку .

  • popitem метод OrderedDict имеет другой подпись. Он принимает необязательный аргумент, чтобы указать, какой элемент выталкивается.

  • OrderedDict имеет метод move_to_end для эффективно переместить элемент в конечную точку.

  • До Python 3.8 у dict не было метода __reversed__.

1
Boris 17 Янв 2020 в 02:36

Начиная с Python 3.7, новое улучшение:

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

Это означает, что больше нет необходимости в OrderedDict 🎉. Они почти одинаковые.


Тем не менее, некоторые незначительные детали, чтобы рассмотреть ...

Но есть различия между Python 3.7+ dict и OrderedDict, продемонстрированные здесь:

from collections import OrderedDict

d = {'b': 1, 'a': 2}
od = OrderedDict([('b', 1), ('a', 2)])

# they are equal with content and order
assert d == od
assert list(d.items()) == list(od.items())
assert repr(dict(od)) == repr(d)

Очевидно, есть разница между строковым представлением двух объектов, с объектом dict в более естественной и компактной форме.

str(d)  # {'b': 1, 'a': 2}
str(od) # OrderedDict([('b', 1), ('a', 2)])

Что касается различных методов между ними, на этот вопрос можно ответить с помощью теории множеств:

d_set = set(dir(d))
od_set = set(dir(od))
od_set.difference(d_set)
# {'__dict__', '__reversed__', 'move_to_end'}

Это означает, что OrderedDict имеет как минимум две функции, которые dict не имеют встроенных, но здесь показаны обходные пути:

# 1) OrderedDict can be reversed (but then what?)
reversed(od)
# <odict_iterator at 0x7fc03f119888>
reversed(d)
# TypeError: 'dict' object is not reversible
# better way to reverse a dict
dict(reversed(list(d.items())))  # {'a': 2, 'b': 1}

# 2) OrderedDict has 'move_to_end' method
od.move_to_end('b')  # now it is: OrderedDict([('a', 2), ('b', 1)])
# dict does not, but similar can be done with
d['b'] = d.pop('b')  # now it is: {'a': 2, 'b': 1}
14
Mike T 10 Фев 2020 в 21:51