Hoe kan ik een woordenboek op sleutel sorteren?

Wat zou een goede manier zijn om van {2:3, 1:89, 4:5, 3:0}naar {1:89, 2:3, 3:0, 4:5}?
Ik heb enkele berichten gecontroleerd, maar ze gebruiken allemaal de “gesorteerde” operator die tupels retourneert.


Antwoord 1, autoriteit 100%

Standaard Python-woordenboeken zijn ongeordend (tot Python 3.7). Zelfs als u de paren (sleutel, waarde) zou sorteren, zou u ze niet kunnen opslaan in een dictop een manier die de volgorde zou behouden.

De gemakkelijkste manier is om OrderedDict, die de volgorde onthoudt waarin de elementen zijn ingevoegd:

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)])

Het maakt niet uit hoe odwordt afgedrukt; het werkt zoals verwacht:

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

Voor gebruikers van Python 3 moet men de .items()gebruiken in plaats van .iteritems():

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

Antwoord 2, autoriteit 43%

Woordenboeken zelf hebben geen bestelde artikelen als zodanig, als u ze wilt afdrukken, enz., zijn hier enkele voorbeelden:

In Python 2.4 en hoger:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}
for key in sorted(mydict):
    print "%s: %s" % (key, mydict[key])

geeft:

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

(Python onder 2.4:)

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

Bron: http://www.saltycrane. com/blog/2007/09/how-to-sort-python-dictionary-by-keys/


Antwoord 3, autoriteit 24%

Voor CPython/PyPy 3.6 en elke Python 3.7 of hoger is dit eenvoudig te doen met:

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

Antwoord 4, autoriteit 20%

Van Python’s collectionsbibliotheekdocumentatie:

>>> 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)])

Antwoord 5, autoriteit 4%

Er zijn een aantal Python-modules die woordenboekimplementaties bieden die de sleutels automatisch in gesorteerde volgorde houden. Overweeg de module sortedcontainersdie pure Python- en fast-as-C-implementaties zijn. Er is ook een prestatievergelijkingmet andere populaire opties die met elkaar worden vergeleken.

Het gebruik van een geordend dictaat is een ontoereikende oplossing als u voortdurend sleutel/waarde-paren moet toevoegen en verwijderen en tegelijkertijd moet herhalen.

>>> 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)]

Het SortedDict-type ondersteunt ook geïndexeerde locatiezoekopdrachten en verwijdering, wat niet mogelijk is met het ingebouwde dict-type.

>>> s.iloc[-1]
4
>>> del s.iloc[2]
>>> s.keys()
SortedSet([1, 2, 4])

Antwoord 6, autoriteit 4%

Gewoon:

d = {2:3, 1:89, 4:5, 3:0}
sd = sorted(d.items())
for k,v in sd:
    print k, v

Uitvoer:

1 89
2 3
3 0
4 5

Antwoord 7, autoriteit 2%

Zoals anderen al hebben gezegd, zijn woordenboeken inherent ongeordend. Als het probleem echter alleen het weergevenvan woordenboeken op een geordende manier is, kunt u de methode __str__in een woordenboeksubklasse overschrijven en deze woordenboekklasse gebruiken in plaats van de ingebouwde dict. Bijv.

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}

Let op, dit verandert niets aan de manier waarop de sleutels worden opgeslagen, de volgorde waarin ze terugkomen wanneer je ze herhaalt, enzovoort, alleen hoe ze worden weergegeven met printof op de python-console.


Antwoord 8, autoriteit 2%

Andere manier gevonden:

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

upd:
1. dit sorteert ook geneste objecten (bedankt @DanielF).
2. Python-woordenboeken zijn ongeordend, daarom is dit alleen geschikt om af te drukken of toe te wijzen aan str.


Antwoord 9, autoriteit 2%

Python-woordenboek was ongeordend vóór Python 3.6. In de CPython-implementatie van Python 3.6 behoudt het woordenboek de invoegvolgorde.
Vanaf Python 3.7 wordt dit een taalfunctie.

In changelog van Python 3.6 (https://docs.python. org/3.6/whatsnew/3.6.html#whatsnew36-compactdict):

Er wordt rekening gehouden met het ordebehoud van deze nieuwe implementatie
een implementatiedetail en er mag niet op worden vertrouwd (dit kan
verandering in de toekomst, maar het is wenselijk om dit nieuwe dictaat te hebben
implementatie in de taal voor een paar releases voordat de
taalspecificatie om ordebehoudende semantiek te verplichten voor alle huidige
en toekomstige Python-implementaties; dit helpt ook om te behouden
achterwaartse compatibiliteit met oudere versies van de taal waarin
willekeurige iteratievolgorde is nog steeds van kracht, b.v. Python 3.5).

In document van Python 3.7 (https://docs.python.org/ 3.7/tutorial/datastructures.html#dictionaries):

Het uitvoeren van list(d) op een woordenboek geeft een lijst met alle gebruikte sleutels
in het woordenboek, in invoegvolgorde(als je het gesorteerd wilt hebben, gebruik dan
in plaats daarvan gesorteerd(d).

Dus in tegenstelling tot eerdere versies, kun je een dictaat sorteren na Python 3.6/3.7. Als u een genest dictaat inclusief het subdict erin wilt sorteren, kunt u het volgende doen:

test_dict = {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': 1}}
def dict_reorder(item):
    return {k: dict_reoder(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


Antwoord 10, autoriteit 2%

In Python 3.

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

geeft

1 89
2 3
3 0
4 5

Antwoord 11

Een gemakkelijke manier om dit te doen:

d = {2:3, 1:89, 4:5, 3:0}
s = {k : d[k] for k in sorted(d)}
s
Out[1]: {1: 89, 2: 3, 3: 0, 4: 5} 

Antwoord 12

U kunt een nieuw woordenboek maken door het huidige woordenboek op sleutel te sorteren volgens uw vraag.

Dit is je woordenboek

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

Maak een nieuw woordenboek d1 door deze d te sorteren met de lambda-functie

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

d1 moet {1: 89, 2: 3, 3: 0, 4: 5} zijn, gesorteerd op sleutels in d.


Antwoord 13

Hier vond ik een eenvoudigste oplossing om het python-dict op sleutel te sorteren met behulp van pprint.
bijv.

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

maar tijdens het gebruik van pprint zal het gesorteerde dictaat retourneren

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

Antwoord 14

Er is een gemakkelijke manier om een ​​woordenboek te sorteren.

Volgens uw vraag,

De oplossing is:

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

(Waar c, de naam van uw woordenboek is.)

Dit programma geeft de volgende output:

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

zoals je wilde.

Een ander voorbeeld is:

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

Geeft de output:['Albert', 'Bill', 'John', 'Lucy', 'Peter']

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

Geeft de uitvoer:[18, 24, 32, 36, 41]

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

Geeft de uitvoer:

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

Dus door het te veranderen in sleutels, waarden en items, kun je afdrukken zoals je wilde. Ik hoop dat dit helpt!


Antwoord 15

Genereert precies wat u wilt:

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}

Maar dit is niet de juiste manier om dit te doen, omdat het een duidelijk gedrag kan vertonen met verschillende woordenboeken, wat ik onlangs heb geleerd. Vandaar dat Tim de perfecte manier heeft voorgesteld in de reactie op mijn vraag die ik hier deel.

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

Antwoord 16

Ik denk dat het het gemakkelijkst is om het dictaat op sleutel te sorteren en het gesorteerde sleutel:waarde-paar in een nieuw dictaat op te slaan.

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]

Om het duidelijker te maken:

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

Antwoord 17

Python-dictaten zijn niet geordend. Meestal is dit geen probleem, aangezien de meest voorkomende use-case is om een ​​zoekopdracht uit te voeren.

De eenvoudigste manier om te doen wat u wilt, is door een collections.OrderedDictte maken en de elementen in gesorteerde volgorde in te voegen.

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

Als je moet herhalen, zoals anderen hierboven hebben gesuggereerd, is de eenvoudigste manier om gesorteerde sleutels te herhalen. Voorbeelden-

Print waarden gesorteerd op sleutels:

# 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

Krijg een lijst met waarden gesorteerd op sleutels:

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

Antwoord 18

Ik bedenk het sorteren van dictaten op één regel.

>> 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]

Ik hoop dat dit nuttig zal zijn.


Antwoord 19

Deze functie sorteert elk woordenboek recursiefop sleutel. Dat wil zeggen, als een waarde in het woordenboek ook een woordenboek is, wordt het ook gesorteerd op sleutel. Als u CPython 3.6 of hoger gebruikt, kan een eenvoudige wijziging worden aangebracht om een ​​dictte gebruiken in plaats van een 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)

Antwoord 20

Jongens, jullie maken het ingewikkeld… het is heel simpel

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

De uitvoer is:

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

Antwoord 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)

Antwoord 22

De eenvoudigste oplossing is dat u een lijst krijgt met de dict-sleutel in gesorteerde volgorde en vervolgens over dict herhaalt. Bijvoorbeeld

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]

Hierna volgt de uitvoer (aflopende volgorde)

e 30
b 13
d 4
c 2
a 1

Antwoord 23

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]}

Antwoord 24

Voor de manier waarop de vraag is geformuleerd, zijn de meeste antwoorden hier correct.

Echter, als je bedenkt hoe de dingen moetenecht gedaan worden, rekening houdend met decennia en decennia van informatica, kom ik tot mijn totale verbazing dat er eigenlijk maar één antwoordhier (van GrantJ-gebruiker) die gebruik voorstelt van gesorteerde associatieve containers (sortedcontainers) die elementen sorteert op basis van sleutel op hun invoegpunt.

Dat voorkomt enormeprestatie-impact per aanroep van sort(...)(minimaal O(N*log(N)), waarbij Nhet aantal elementen is (logischerwijs geldt dit voor al dergelijke oplossingen hier die suggereren om de sort(...)te gebruiken). dat voor al dergelijke oplossingen de sort(...)moet worden aangeroepen telkens wanneer de verzameling als gesorteerd moet worden geopend NAhet werd gewijzigd door toevoegen/verwijderen elementen …


Antwoord 25

Een eenvoudige manier die ik heb gevonden om een ​​woordenboek te sorteren, is door een nieuw woordenboek te maken op basis van de gesorteerde key:value-items van degene die je probeert te sorteren.
Als u dict = {}wilt sorteren, haalt u alle items op met de bijbehorende methode, sorteert u ze met de functie sorted()en maakt u vervolgens het nieuwe woordenboek.

Hier is de code met woordenboekbegrip:

sorted_dict = {k:v for k,v in sorted(dict.items())}

Antwoord 26

Een timingvergelijking van de twee methoden in 2.7 laat zien dat ze vrijwel identiek zijn:

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

Antwoord 27

Of gebruik pandas,

Demo:

>>> d={'B':1,'A':2,'C':3}
>>> df=pd.DataFrame(d,index=[0]).sort_index(axis=1)
   A  B  C
0  2  1  3
>>> df.to_dict('int')[0]
{'A': 2, 'B': 1, 'C': 3}
>>> 

Zie:

Documenten hiervan

Documentatie van hele panda’s


Antwoord 28

Er zijn hier al veel antwoorden die populaire manieren laten zien om een ​​Python-woordenboek te sorteren. Ik dacht dat ik nog een paar minder voor de hand liggende manieren zou toevoegen voor degenen die hier van Google komen en op zoek zijn naar niet-standaard ideeën.

Voorbeeldwoordenboek: d = {2: 'c', 1: 'b', 0: 'a', 3: 'd'}

Woordenboekbegrip

# Converts to list, sorts, re-converts to dict
{k: v for k, v in sorted(list(d))}

Lambda’s gebruiken

Sorteren is niet altijd bedoeld om strikt in oplopende of aflopende volgorde te sorteren. Gebruik voor meer voorwaardelijke sortering de bovenstaande methode in combinatie met lamdas:

{k: v for k, v in sorted(d.items(), key=lambda v: ord(v[1]))}

Meer voorbeelden

Deze thread staat al vol genoeg goede voorbeelden. Voor wat meer voorbeelden, evenals randgevallen en eigenaardigheden bekijk dit artikelover het sorteren van woordenboeken in Python.


Antwoord 29

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)

Antwoord 30

Mijn suggestie is dit omdat je hiermee een dictaat kunt sorteren of een dictaat gesorteerd kunt houden terwijl je items toevoegt en in de toekomst mogelijk items moet toevoegen:

Bouw gaandeweg een dicthelemaal opnieuw. Zorg voor een tweede gegevensstructuur, een lijst, met uw lijst met sleutels. Het bisect-pakket heeft een insort-functie waarmee u in een gesorteerde lijst kunt invoegen of uw lijst kunt sorteren nadat u uw dictaat volledig hebt ingevuld. Wanneer u nu uw dictaat herhaalt, herhaalt u in plaats daarvan de lijst om toegang te krijgen tot elke sleutel op een geordende manier zonder u zorgen te maken over de weergave van de dictaatstructuur (die niet is gemaakt om te sorteren).

Other episodes