Как я могу отсортировать словарь по ключу? - PullRequest
778 голосов
/ 25 января 2012

Что было бы хорошим способом перейти от {2:3, 1:89, 4:5, 3:0} к {1:89, 2:3, 3:0, 4:5}?
Я проверил несколько сообщений, но все они используют оператор "сортировка", который возвращает кортежи.

Ответы [ 24 ]

825 голосов
/ 25 января 2012

Стандартные словари Python неупорядочены.Даже если вы сортируете пары (ключ, значение), вы не сможете сохранить их в dict таким образом, чтобы сохранить порядок.

Самый простой способ - использовать OrderedDict, который запоминает порядок, в котором были вставлены элементы:

In [1]: import collections

In [2]: d = {2:3, 1:89, 4:5, 3:0}

In [3]: od = collections.OrderedDict(sorted(d.items()))

In [4]: od
Out[4]: OrderedDict([(1, 89), (2, 3), (3, 0), (4, 5)])

Не важно, как распечатывается od;все будет работать как положено:

In [11]: od[1]
Out[11]: 89

In [12]: od[3]
Out[12]: 0

In [13]: for k, v in od.iteritems(): print k, v
   ....: 
1 89
2 3
3 0
4 5

Python 3

Для пользователей Python 3 необходимо использовать .items() вместо .iteritems():

In [13]: for k, v in od.items(): print(k, v)
   ....: 
1 89
2 3
3 0
4 5
383 голосов
/ 21 декабря 2012

В самих словарях нет упорядоченных элементов как таковых, если вы хотите распечатать их и т. Д. В некотором порядке, вот несколько примеров:

В Python 2.4 и выше:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

for key in sorted(mydict):
    print "%s: %s" % (key, mydict[key])

дает:

alan: 2
bob: 1
carl: 40
danny: 3

(Python ниже 2.4:)

keylist = mydict.keys()
keylist.sort()
for key in keylist:
    print "%s: %s" % (key, mydict[key])

Источник: http://www.saltycrane.com/blog/2007/09/how-to-sort-python-dictionary-by-keys/

190 голосов
/ 03 марта 2013

Из Библиотеки Python collections :

>>> from collections import OrderedDict

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key -- OrderedDict(sorted(d.items()) also works
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
72 голосов
/ 30 октября 2017

Для python3.6 + это легко сделать с помощью:

>>> d = {2:3, 1:89, 4:5, 3:0}
>>> dict(sorted(d.items()))
{1: 89, 2: 3, 3: 0, 4: 5}
40 голосов
/ 28 марта 2014

Существует ряд модулей Python, которые предоставляют реализации словаря, которые автоматически поддерживают ключи в отсортированном порядке.Рассмотрим модуль sortedcontainers , который является реализациями на чистом Python и fast-as-C.Существует также сравнение производительности с другими популярными опциями, сравниваемыми друг с другом.

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

>>> from sortedcontainers import SortedDict
>>> d = {2:3, 1:89, 4:5, 3:0}
>>> s = SortedDict(d)
>>> s.items()
[(1, 89), (2, 3), (3, 0), (4, 5)]

Тип SortedDict также поддерживает индексированный поиск и удаление местоположения, что невозможно при встроенном типе dict.

>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])
25 голосов
/ 13 ноября 2015

Просто:

d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())

for k,v in sd:
    print k, v

Вывод:

1 89
2 3
3 0
4 5
24 голосов
/ 25 января 2012

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

class SortedDisplayDict(dict):
   def __str__(self):
       return "{" + ", ".join("%r: %r" % (key, self[key]) for key in sorted(self)) + "}"


>>> d = SortedDisplayDict({2:3, 1:89, 4:5, 3:0})
>>> d
{1: 89, 2: 3, 3: 0, 4: 5}

Обратите внимание, что это ничего не меняет в том, как хранятся ключи, в каком порядке они будут возвращаться, когда вы перебираете их, и т. Д., Как они отображаются с помощью print или на консоли python.

17 голосов
/ 13 марта 2014

Нашел другой способ:

import json
print json.dumps(d, sort_keys = True)

UPD:
1. это также сортирует вложенные объекты (спасибо @DanielF).
2. Словари python неупорядочены, поэтому это подходит для печати или присваивания только str.

16 голосов
/ 17 декабря 2013

В Python 3.

>>> D1 = {2:3, 1:89, 4:5, 3:0}
>>> for key in sorted(D1):
    print (key, D1[key])

дает

1 89
2 3
3 0
4 5
11 голосов
/ 08 января 2018

Словарь Python был неупорядочен до Python 3.6.В реализации Python 3.6 для CPython словарь сохраняет порядок вставки.В Python 3.7 это станет функцией языка.

В журнале изменений Python 3.6 (https://docs.python.org/3.6/whatsnew/3.6.html#whatsnew36-compactdict):

Сохраняющий порядок аспект этой новой реализации рассматривается как деталь реализации ина него не следует полагаться (это может измениться в будущем, но желательно иметь эту новую реализацию dict на языке в течение нескольких выпусков, прежде чем изменять спецификацию языка, чтобы предписывать семантику сохранения порядка для всех текущих и будущих реализаций Python;также помогает сохранить обратную совместимость со старыми версиями языка, где все еще действует случайный порядок итераций, например, Python 3.5).

В документе Python 3.7 (https://docs.python.org/3.7/tutorial/datastructures.html#dictionaries):

Выполнение list (d) в словаре возвращает список всех ключей, используемых в словаре, в порядке вставки (если вы хотите, чтобы он был отсортирован, просто используйте вместо него sorted (d)).

Таким образом, в отличие от предыдущих версий, вы можете отсортировать dict после Python 3.6 / 3.7. Если вы хотите отсортировать nesТед Дикт, включая субдикт внутри, вы можете сделать:

test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}

def dict_reorder(item):
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

reordered_dict = dict_reorder(test_dict)

https://gist.github.com/ligyxy/f60f0374defc383aa098d44cfbd318eb

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...