Hoe sorteer ik een woordenboek op waarde?

Ik heb een woordenboek met waarden die worden gelezen uit twee velden in een database: een tekenreeksveld en een numeriek veld. Het stringveld is uniek, dus dat is de sleutel van het woordenboek.

Ik kan sorteren op de sleutels, maar hoe kan ik sorteren op basis van de waarden?

Opmerking: ik heb de Stack Overflow-vraag hier gelezen Hoe sorteer ik een lijst met woordenboeken op een waarde van het woordenboek? en zou waarschijnlijk mijn code kunnen veranderen om een ​​lijst met woordenboeken te hebben, maar aangezien ik niet echt een lijst met woordenboeken nodig heb, wilde ik weten of er een eenvoudigere oplossing is om ofwel in oplopende of aflopende volgorde te sorteren.


Antwoord 1, autoriteit 100%

Python 3.7+ of CPython 3.6

Dictaten behouden de invoegvolgorde in Python 3.7+. Hetzelfde in CPython 3.6, maar het is een implementatiedetail.

>>> x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> {k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

of

>>> dict(sorted(x.items(), key=lambda item: item[1]))
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

Oudere Python

Het is niet mogelijk om een ​​woordenboek te sorteren, alleen om een ​​weergave te krijgen van een woordenboek dat is gesorteerd. Woordenboeken zijn inherent geordend, maar andere typen, zoals lijsten en tupels, zijn dat niet. U hebt dus een geordend gegevenstype nodig om gesorteerde waarden weer te geven, wat een lijst zal zijn, waarschijnlijk een lijst met tupels.

Bijvoorbeeld

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x is een lijst met tuples gesorteerd op het tweede element in elke tupel. dict(sorted_x) == x.

En voor degenen die willen sorteren op sleutels in plaats van waarden:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

In Python3 sinds uitpakken is niet toegestaan die we kunnen gebruiken

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])

Als je de uitvoer als een dictaat wilt, kun je collections.OrderedDict:

import collections
sorted_dict = collections.OrderedDict(sorted_x)

Antwoord 2, autoriteit 24%

Zo simpel als: sorted(dict1, key=dict1.get)

Nou, het is eigenlijk mogelijk om een ​​”sorteer op woordenboekwaarden” uit te voeren. Onlangs moest ik dat doen in een Code Golf (Stack Overflow-vraag Code golf: Woordfrequentiegrafiek). Samengevat, het probleem was van het soort: geef een tekst, tel hoe vaak elk woord wordt aangetroffen en geef een lijst weer van de topwoorden, gesorteerd op afnemende frequentie.

Als u een woordenboek maakt met de woorden als sleutels en het aantal keren dat elk woord voorkomt als waarde, hier vereenvoudigd als:

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
    d[w] += 1

dan kun je een lijst met woorden krijgen, gerangschikt op gebruiksfrequentie met sorted(d, key=d.get) – de sortering herhaalt zich over de woordenboeksleutels, waarbij het aantal woordvermeldingen als sorteersleutel wordt gebruikt.

for w in sorted(d, key=d.get, reverse=True):
    print(w, d[w])

Ik schrijf deze gedetailleerde uitleg om te illustreren wat mensen vaak bedoelen met “Ik kan een woordenboek gemakkelijk op sleutel sorteren, maar hoe sorteer ik op waarde” – en ik denk dat de oorspronkelijke post een dergelijk probleem probeerde aan te pakken. En de oplossing is om een ​​soort lijst met sleutels te maken, gebaseerd op de waarden, zoals hierboven weergegeven.


Antwoord 3, autoriteit 17%

Je zou kunnen gebruiken:

sorted(d.items(), key=lambda x: x[1])

Dit sorteert het woordenboek op de waarden van elk item in het woordenboek, van klein naar groot.

Om het in aflopende volgorde te sorteren, voegt u gewoon reverse=True toe:

sorted(d.items(), key=lambda x: x[1], reverse=True)

Invoer:

d = {'one':1,'three':3,'five':5,'two':2,'four':4}
a = sorted(d.items(), key=lambda x: x[1])    
print(a)

Uitvoer:

[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]

Antwoord 4, autoriteit 4%

Dictaten kunnen niet worden gesorteerd, maar u kunt er wel een gesorteerde lijst van maken.

Een gesorteerde lijst met dict-waarden:

sorted(d.values())

Een lijst met (sleutel, waarde) paren, gesorteerd op waarde:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))

Antwoord 5, autoriteit 3%

In recente Python 2.7 hebben we de nieuwe OrderedDict type, dat de volgorde onthoudt waarin de items zijn toegevoegd.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}
>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1
>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

Een nieuw geordend woordenboek maken van het origineel, sorteren op de waarden:

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

De OrderedDict gedraagt ​​zich als een normaal dictaat:

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4
>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])

Antwoord 6, autoriteit 2%

UPDATE: 5 DECEMBER 2015 met Python 3.5

Hoewel ik het geaccepteerde antwoord nuttig vond, was ik ook verrast dat het niet is bijgewerkt om te verwijzen naar OrderedDict uit de standaardbibliotheek collections-module als een levensvatbaar, modern alternatief – ontworpen om precies dit soort problemen op te lossen.

from operator import itemgetter
from collections import OrderedDict
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

De officiële OrderedDict documentatie biedt ook een vergelijkbaar voorbeeld, maar met een lambda voor de sorteerfunctie:

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

Antwoord 7, autoriteit 2%

Vrijwel hetzelfde als Hank Gay’s antwoord:

sorted([(value,key) for (key,value) in mydict.items()])

Of enigszins geoptimaliseerd zoals voorgesteld door John Fouhy:

sorted((value,key) for (key,value) in mydict.items())

Antwoord 8

Het kan vaak erg handig zijn om namedtuple te gebruiken . U heeft bijvoorbeeld een woordenboek met ‘naam’ als sleutels en ‘score’ als waarden en u wilt sorteren op ‘score’:

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

sorteren met de laagste score eerst:

worst = sorted(Player(v,k) for (k,v) in d.items())

sorteren met de hoogste score eerst:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

Nu kun je de naam en score krijgen van, laten we zeggen de op één na beste speler (index=1), heel Python-achtig als volgt:

player = best[1]
player.name
    'Richard'
player.score
    7

Antwoord 9

Vanaf Python 3.6 wordt het ingebouwde dictaat besteld

Goed nieuws, dus het oorspronkelijke gebruik van het OP van toewijzingsparen die zijn opgehaald uit een database met unieke tekenreeks-ID’s als sleutels en numerieke waarden als waarden in een ingebouwd Python v3.6+ dictaat, zou nu de invoegvolgorde moeten respecteren.

Als zeg de resulterende twee kolom tabeluitdrukkingen van een databasequery zoals:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

wordt opgeslagen in twee Python-tupels, k_seq en v_seq (uitgelijnd door numerieke index en met dezelfde lengte natuurlijk), dan:

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

Toestaan ​​om later uit te voeren als:

for k, v in ordered_map.items():
    print(k, v)

opbrengst in dit geval (voor de nieuwe Python 3.6+ ingebouwde dict!):

foo 0
bar 1
baz 42

in dezelfde volgorde per waarde van v.

Waar in de installatie van Python 3.5 op mijn machine het momenteel oplevert:

bar 1
foo 0
baz 42

Details:

Zoals voorgesteld in 2012 door Raymond Hettinger (zie mail op python-dev met onderwerp “Compactere woordenboeken met snellere iteratie”) en nu (in 2016) aangekondigd in een mail van Victor Stinner aan python-dev met onderwerp “Python 3.6 dict wordt compact en krijgt een privéversie; en trefwoorden worden geordend” als gevolg van de reparatie/implementatie van issue 27350 “Compact en geordend dict” in Python 3.6 kunnen we nu een ingebouwde dict om de volgorde van invoegen te behouden!!

Hopelijk zal dit leiden tot een dunne laag OrderedDict-implementatie als eerste stap. Zoals @JimFasarakis-Hilliard aangaf, zien sommigen ook in de toekomst gebruiksscenario’s voor het type OrderedDict. Ik denk dat de Python-gemeenschap in het algemeen zorgvuldig zal onderzoeken of dit de tand des tijds zal doorstaan ​​en wat de volgende stappen zullen zijn.

Tijd om onze codeergewoonten te heroverwegen om de mogelijkheden niet te missen die worden geopend door stabiel bestellen van:

  • Zoekwoordargumenten en
  • (tussentijdse) dictaatopslag

De eerste omdat het in sommige gevallen de implementatie van functies en methoden vereenvoudigt.

De tweede omdat het aanmoedigt om gemakkelijker dicts te gebruiken als tussentijdse opslag in verwerkingspijplijnen.

Raymond Hettinger was zo vriendelijk om documentatie te verstrekken met uitleg over “The Tech Behind Python 3.6 Dictionaries” – uit zijn San Francisco Python Meetup Group-presentatie 2016-DEC-08.

En misschien zullen nogal wat Stack Overflow hoog ingerichte vraag- en antwoordpagina’s varianten van deze informatie ontvangen en voor veel antwoorden van hoge kwaliteit is ook een update per versie vereist.

Voorbehoud Emptor (maar zie ook onderstaande update 2017-12-15):

Zoals @ajcr terecht opmerkt: “Het orderbehoud-aspect van deze nieuwe implementatie wordt beschouwd als een implementatiedetail en er mag niet op worden vertrouwd.” (van de whatsnew36) geen nitpicking, maar het citaat was een beetje pessimistisch gesneden ;-). Het gaat verder als ” (dit kan in de toekomst veranderen, maar het is wenselijk om deze nieuwe dict-implementatie in de taal te hebben voor een paar releases voordat de taalspecificatie wordt gewijzigd om ordebehoudende semantiek te verplichten voor alle huidige en toekomstige Python-implementaties; dit ook helpt achterwaartse compatibiliteit te behouden met oudere versies van de taal waar willekeurige iteratievolgorde nog steeds van kracht is, bijvoorbeeld Python 3.5).”

Dus zoals in sommige menselijke talen (bijv. Duits), vormt het gebruik de taal, en de wil is nu verklaard … in whatsnew36.

Update 2017-12-15:

In een mail naar de python-dev-lijst, verklaarde Guido van Rossum:

Maak het zo. “Dict behoudt invoegvolgorde” is de uitspraak. Bedankt!

Dus het versie 3.6 CPython-neveneffect van het invoegen van dictaten wordt nu onderdeel van de taalspecificatie (en niet langer alleen een implementatiedetail). Die mailthread bracht ook enkele onderscheidende ontwerpdoelen naar voren voor collections.OrderedDict, zoals Raymond Hettinger er tijdens de discussie aan herinnerde.


Antwoord 10

Ik had hetzelfde probleem en heb het als volgt opgelost:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(Mensen die antwoorden “Het is niet mogelijk om een ​​dictaat te sorteren” hebben de vraag niet gelezen! Sterker nog, “Ik kan sorteren op de toetsen, maar hoe kan ik sorteren op basis van de waarden?” betekent duidelijk dat hij wil een lijst van de sleutels gesorteerd op de waarde van hun waarden.)

Houd er rekening mee dat de volgorde niet goed is gedefinieerd (sleutels met dezelfde waarde staan ​​in een willekeurige volgorde in de uitvoerlijst).


Antwoord 11

Als waarden numeriek zijn, kunt u ook Counter gebruiken uit collecties.

from collections import Counter
x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())
>> [('python', 5), ('world', 3), ('hello', 1)]    

Antwoord 12

Doe in Python 2.7 gewoon:

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
# dictionary sorted by key
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)])

kopiëren en plakken van: http://docs.python.org/ dev/library/collections.html#ordereddict-examples-and-recipes

Geniet 😉


Antwoord 13

Dit is de code:

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo
print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo
print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

Dit zijn de resultaten:

Origineel

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

Rofl

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

Rangorde

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}

Antwoord 14

Probeer de volgende aanpak. Laten we een woordenboek definiëren met de naam mydict met de volgende gegevens:

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

Als men het woordenboek op sleutels wil sorteren, kan men zoiets doen als:

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

Dit zou de volgende uitvoer moeten opleveren:

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

Aan de andere kant, als men een woordenboek op waarde wil sorteren (zoals in de vraag wordt gesteld), zou men het volgende kunnen doen:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

Het resultaat van deze opdracht (het woordenboek op waarde sorteren) zou het volgende moeten opleveren:

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

Antwoord 15

Vanaf Python 3.6 worden dict objecten nu geordend op invoegvolgorde. Het staat officieel in de specificaties van Python 3.7.

>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}

Daarvoor moest je OrderedDict gebruiken.

Python 3.7-documentatie zegt:

Gewijzigd in versie 3.7: Woordenboekvolgorde is gegarandeerd invoeging
bestellen. Dit gedrag was een implementatiedetail van CPython vanaf 3.6.


Antwoord 16

U kunt ook een “omgekeerde index” maken

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

Nu heeft je inverse de waarden; elke waarde heeft een lijst met toepasselijke sleutels.

for k in sorted(inverse):
    print k, inverse[k]

Antwoord 17

Je kunt de collections.Counter gebruiken. Let op, dit werkt voor zowel numerieke als niet-numerieke waarden.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

Antwoord 18

U kunt ook een aangepaste functie gebruiken die aan de sleutel kan worden doorgegeven.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

Antwoord 19

Je kunt een skip dict gebruiken, een woordenboek dat permanent op waarde is gesorteerd.

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

Als je keys(), values() of items() gebruikt, dan herhaal je in gesorteerde volgorde op waarde.

Het is geïmplementeerd met behulp van de gegevensstructuur skip list.


Antwoord 20

from django.utils.datastructures import SortedDict
def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict

Antwoord 21

Onthoud natuurlijk dat je OrderedDict moet gebruiken omdat reguliere Python-woordenboeken de oorspronkelijke volgorde niet behouden.

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))

Als je Python 2.7 of hoger niet hebt, kun je het beste de waarden in een generatorfunctie herhalen. (Er is een OrderedDict voor 2.4 en 2.6 hier, maar

a) Ik weet niet hoe goed het werkt

en

b) Je moet het natuurlijk downloaden en installeren. Als je geen beheerderstoegang hebt, ben ik bang dat de optie niet beschikbaar is.)


def gen(originalDict):
    for x, y in sorted(zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 
for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

U kunt ook elke waarde afdrukken

for bleh, meh in gen(myDict):
    print(bleh, meh)

Vergeet niet om de haakjes na het afdrukken te verwijderen als u Python 3.0 of hoger niet gebruikt


Antwoord 22

Zoals aangegeven door Dilettant, zal Python 3.6 nu de bestelling behouden! Ik dacht dat ik een functie zou delen die ik heb geschreven die het sorteren van een iterabel (tupel, lijst, dictaat) vergemakkelijkt. In het laatste geval kunt u sorteren op sleutels of waarden, en er kan rekening worden gehouden met numerieke vergelijking. Alleen voor >= 3.6!

Wanneer u probeert gesorteerd te gebruiken op een iterable die b.v. strings en ints, zal gesorteerd() mislukken. Natuurlijk kun je stringvergelijking forceren met str(). In sommige gevallen wilt u echter een werkelijke numerieke vergelijking maken waarbij 12 kleiner is dan 20 (wat niet het geval is bij tekenreeksvergelijking). Dus kwam ik op het volgende. Als u expliciete numerieke vergelijking wilt, kunt u de vlag num_as_num gebruiken die zal proberen om expliciete numerieke sortering uit te voeren door te proberen alle waarden om te zetten in floats. Als dat lukt, zal het numeriek sorteren, anders zal het zijn toevlucht nemen tot stringvergelijking.

Opmerkingen voor verbetering welkom.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))
      return _sorted
    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")

Antwoord 23

Hier is een oplossing met zip op d.values() en d.keys(). Een paar regels verder via deze link (op objecten in de woordenboekweergave) is:

Hiermee kunnen (waarde, sleutel) paren worden gemaakt met zip(): pairs = zip(d.values(), d.keys()).

We kunnen dus het volgende doen:

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}
d_sorted = sorted(zip(d.values(), d.keys()))
print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]

Antwoord 24

Gebruik ValueSortedDict van dictaten:

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

Antwoord 25

Net relevante vaardigheid geleerd van Python voor iedereen .

U kunt een tijdelijke lijst gebruiken om u te helpen bij het sorteren van het woordenboek:

#Assume dictionary to be:
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
# create a temporary list
tmp = []
# iterate through the dictionary and append each tuple into the temporary list 
for key, value in d.items():
    tmptuple = (value, key)
    tmp.append(tmptuple)
# sort the list in ascending order
tmp = sorted(tmp)
print (tmp)

Als u de lijst in aflopende volgorde wilt sorteren, wijzigt u eenvoudig de oorspronkelijke sorteerregel in:

tmp = sorted(tmp, reverse=True)

Bij gebruik van lijstbegrip zou de oneliner zijn:

#Assuming the dictionary looks like
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))

Voorbeelduitvoer:

#Asending order
[(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]

Antwoord 26

Herhaal een dictaat en sorteer het op zijn waarden in aflopende volgorde:

$ python --version
Python 3.2.2
$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(word, dictionary[word])
$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1

Antwoord 27

Als uw waarden gehele getallen zijn en u Python 2.7 of nieuwer gebruikt, kunt u collections.Counter in plaats van dict. De most_common methode geeft je alle items, gesorteerd op waarde.


Antwoord 28

Dit werkt in 3.1.x:

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)

Antwoord 29

Voor de volledigheid post ik een oplossing met behulp van heapq. Let op, deze methode werkt voor zowel numerieke als niet-numerieke waarden

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

Antwoord 30

months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
          "June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
          "November": 30, "December": 31}
def mykey(t):
    """ Customize your sorting logic using this function.  The parameter to
    this function is a tuple.  Comment/uncomment the return statements to test
    different logics.
    """
    return t[1]              # sort by number of days in the month
    #return t[1], t[0]       # sort by number of days, then by month name
    #return len(t[0])        # sort by length of month name
    #return t[0][-1]         # sort by last character of month name
# Since a dictionary can't be sorted by value, what you can do is to convert
# it into a list of tuples with tuple length 2.
# You can then do custom sorts by passing your own function to sorted().
months_as_list = sorted(months.items(), key=mykey, reverse=False)
for month in months_as_list:
    print month

LEAVE A REPLY

Please enter your comment!
Please enter your name here

5 × two =

Other episodes