Как я могу сортировать словарь по ключу?

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

Ответ 1

Стандартные словари 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

Ответ 2

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

В 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/

Ответ 3

Из Документация по библиотеке 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)])

Ответ 4

Для CPython/PyPy 3.6 и любого Python 3.7 или выше это легко сделать с помощью:

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

Ответ 5

Существует несколько модулей Python, которые предоставляют реализации словаря, которые автоматически поддерживают ключи в отсортированном порядке. Рассмотрим модуль sortedcontainers, который является реализацией с использованием pure-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])

Ответ 6

Просто:

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

Ответ 7

Как уже упоминалось, словари по своей сути неупорядочены. Однако, если проблема - это просто отображение словарей упорядоченным образом, вы можете переопределить метод __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.

Ответ 8

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

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

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

Ответ 9

В 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

Ответ 10

Словарь 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)).

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

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

Ответ 11

Здесь я нашел простейшее решение для сортировки ключа python с помощью pprint. например.

>>> x = {'a': 10, 'cd': 20, 'b': 30, 'az': 99} 
>>> print x
{'a': 10, 'b': 30, 'az': 99, 'cd': 20}

но при использовании pprint он вернет отсортированный dict

>>> import pprint 
>>> pprint.pprint(x)
{'a': 10, 'az': 99, 'b': 30, 'cd': 20}

Ответ 12

Существует простой способ сортировки словаря.

Согласно вашему вопросу,

Решение:

c={2:3, 1:89, 4:5, 3:0}
y=sorted(c.items())
print y

(где c, - название вашего словаря.)

Эта программа дает следующий вывод:

[(1, 89), (2, 3), (3, 0), (4, 5)]

как хотелось.

Другой пример:

d={"John":36,"Lucy":24,"Albert":32,"Peter":18,"Bill":41}
x=sorted(d.keys())
print x

Выдает вывод: ['Albert', 'Bill', 'John', 'Lucy', 'Peter']

y=sorted(d.values())
print y

Выдает результат: [18, 24, 32, 36, 41]

z=sorted(d.items())
print z

Выдает вывод:

[('Albert', 32), ('Bill', 41), ('John', 36), ('Lucy', 24), ('Peter', 18)]

Следовательно, изменяя его на клавиши, значения и элементы, вы можете печатать как то, что вам нужно. Надеюсь, это поможет!

Ответ 13

Будет генерировать именно то, что вы хотите:

 D1 = {2:3, 1:89, 4:5, 3:0}

 sort_dic = {}

 for i in sorted(D1):
     sort_dic.update({i:D1[i]})
 print sort_dic


{1: 89, 2: 3, 3: 0, 4: 5}

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

from collections import OrderedDict
sorted_dict = OrderedDict(sorted(D1.items(), key=lambda t: t[0]))

Ответ 14

Я думаю, что проще всего отсортировать ключ dict и сохранить отсортированную пару: значение в новом dict.

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be neccessary
        dict2[key] = dict1[key]

Чтобы сделать его более понятным:

dict1 = {'renault': 3, 'ford':4, 'volvo': 1, 'toyota': 2} 
dict2 = {}                  # create an empty dict to store the sorted     values
for key in sorted(dict1.keys()):
    if not key in dict2:    # Depending on the goal, this line may not be  neccessary
        value = dict1[key]
        dict2[key] = value

Ответ 15

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

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

ordered_dict = collections.OrderedDict([(k, d[k]) for k in sorted(d.keys())])

Если вам нужно повторить, как предложили другие выше, самым простым способом было бы перебрать отсортированные ключи. Примеры -

Значения печати, отсортированные по ключам:

# create the dict
d = {k1:v1, k2:v2,...}
# iterate by keys in sorted order
for k in sorted(d.keys()):
    value = d[k]
    # do something with k, value like print
    print k, value

Получить список значений, отсортированных по ключам:

values = [d[k] for k in sorted(d.keys())]

Ответ 16

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

Это твой словарь

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

Создайте новый словарь d1, отсортировав его с помощью лямбда-функции

d1 = dict(sorted(d.items(), key = lambda x:x[0]))

d1 должно быть {1: 89, 2: 3, 3: 0, 4: 5}, отсортировано по ключам в d.

Ответ 17

Я придумываю однострочную сортировку.

>> a = {2:3, 1:89, 4:5, 3:0}
>> c = {i:a[i] for i in sorted(a.keys())}
>> print(c)
{1: 89, 2: 3, 3: 0, 4: 5}
[Finished in 0.4s]

Надеюсь, это будет полезно.

Ответ 18

Ребята, вы делаете все сложнее... это действительно просто

from pprint import pprint
Dict={'B':1,'A':2,'C':3}
pprint(Dict)

Вывод:

{'A':2,'B':1,'C':3}

Ответ 19

Самое простое решение состоит в том, что вы должны получить список ключей dict, отсортированный по порядку, а затем итерацию по dict. Например

a1 = {'a':1, 'b':13, 'd':4, 'c':2, 'e':30}
a1_sorted_keys = sorted(a1, key=a1.get, reverse=True)
for r in a1_sorted_keys:
    print r, a1[r]

Ниже будет вывод (порядок ожидания)

e 30
b 13
d 4
c 2
a 1

Ответ 20

Сравнение времени двух методов из 2.7 показывает, что они практически идентичны:

>>> setup_string = "a = sorted(dict({2:3, 1:89, 4:5, 3:0}).items())"
>>> timeit.timeit(stmt="[(k, val) for k, val in a]", setup=setup_string, number=10000)
0.003599141953657181

>>> setup_string = "from collections import OrderedDict\n"
>>> setup_string += "a = OrderedDict({1:89, 2:3, 3:0, 4:5})\n"
>>> setup_string += "b = a.items()"
>>> timeit.timeit(stmt="[(k, val) for k, val in b]", setup=setup_string, number=10000)
0.003581275490432745 

Ответ 21

from operator import itemgetter
# if you would like to play with multiple dictionaries then here you go:
# Three dictionaries that are composed of first name and last name.
user = [
    {'fname': 'Mo', 'lname': 'Mahjoub'},
    {'fname': 'Abdo', 'lname': 'Al-hebashi'},
    {'fname': 'Ali', 'lname': 'Muhammad'}
]
#  This loop will sort by the first and the last names.
# notice that in a dictionary order doesn't matter. So it could put the first name first or the last name first. 
for k in sorted (user, key=itemgetter ('fname', 'lname')):
    print (k)

# This one will sort by the first name only.
for x in sorted (user, key=itemgetter ('fname')):
    print (x)

Ответ 22

dictionary = {1:[2],2:[],5:[4,5],4:[5],3:[1]}

temp=sorted(dictionary)
sorted_dict = dict([(k,dictionary[k]) for i,k in enumerate(temp)])

sorted_dict:
         {1: [2], 2: [], 3: [1], 4: [5], 5: [4, 5]}

Ответ 24

Эта функция будет рекурсивно сортировать любой словарь по его ключу. То есть, если какое-либо значение в словаре также является словарем, оно также будет отсортировано по его ключу. Если вы работаете на CPython 3.6 или выше, можно выполнить простое изменение, чтобы использовать dict вместо OrderedDict.

from collections import OrderedDict

def sort_dict(d):
    items = [[k, v] for k, v in sorted(d.items(), key=lambda x: x[0])]
    for item in items:
        if isinstance(item[1], dict):
            item[1] = sort_dict(item[1])
    return OrderedDict(items)
    #return dict(items)

Ответ 25

Используйте sorted ключевое слово: -

d = {2:3, 1:89, 4:5, 3:0}
print(f'Our Dictionary:\t {d} ')
d = dict ( sorted(d.items()) )
print(f'Dictionary after sorted {d} ')

Выход

Our Dictionary:  {2: 3, 1: 89, 4: 5, 3: 0} 
Dictionary after sorted {1: 89, 2: 3, 3: 0, 4: 5} 

Ответ 26

Другой питонический подход будет

def sort_dict(my_dict):
    return sorted(my_dict.items(), key=lambda x :x[1])


Ответ 27

l = dict.keys()
l2 = l
l2.append(0)
l3 = []
for repeater in range(0, len(l)):
    smallnum = float("inf")
    for listitem in l2:
        if listitem < smallnum:
            smallnum = listitem
    l2.remove(smallnum)
    l3.append(smallnum)
l3.remove(0)
l = l3

for listitem in l:
    print(listitem)

Ответ 28

Если у вас есть dict, например:

not_ordered_dict = {5 : "5555", 9 : "9999", 1 : "1111"}

ordered_dict = {}

for key in sorted(not_ordered_dict):
    ordered_dict[key] = not_ordered_dict[key]