python sorted - Come si ordina un dizionario in base al valore?




salvare (25)

Ho un dizionario di valori letti da due campi in un database: un campo stringa e un campo numerico. Il campo stringa è unico, quindi questa è la chiave del dizionario.

Posso ordinare i tasti, ma come posso ordinare in base ai valori?

Nota: ho letto question Come faccio a ordinare una lista di dizionari in base ai valori del dizionario in Python? e probabilmente potrebbe cambiare il mio codice per avere un elenco di dizionari, ma poiché non ho davvero bisogno di un elenco di dizionari, volevo sapere se esiste una soluzione più semplice.


Answers

Questo restituisce l'elenco delle coppie chiave-valore nel dizionario, ordinate per valore dal più alto al più basso:

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

Per il dizionario ordinato per chiave, utilizzare quanto segue:

sorted(d.items(), reverse=True)

Il ritorno è una lista di tuple perché i dizionari stessi non possono essere ordinati.

Questo può essere sia stampato che inviato ad ulteriori calcoli.


Scorrere un ditt e ordinarlo in base ai suoi valori in ordine decrescente:

$ 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

Puoi anche creare un "indice invertito"

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

Ora la tua inversa ha i valori; ogni valore ha un elenco di chiavi applicabili.

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

Dizionario fornito

e = {1:39, 4:34, 7:110, 2:87}

Ordinamento

sred = sorted(e.items(), key=lambda value: value[1])

Risultato

[(4, 34), (1, 39), (2, 87), (7, 110)]

È possibile utilizzare una funzione lambda per ordinare le voci per valore e memorizzarle elaborate all'interno di una variabile, in questo caso sred con e il dizionario originale.

Spero che sia d'aiuto!


Semplice come: sorted(dict1, key=dict1.get)

Bene, in realtà è possibile fare un "ordinamento per valori di dizionario". Recentemente ho dovuto farlo in un Code Golf ( question Code golf: Word frequency chart ). Ridotto, il problema era del tipo: dato un testo, conta quante volte ogni parola viene incontrata e mostra un elenco delle parole migliori, ordinate per frequenza decrescente.

Se costruisci un dizionario con le parole come chiavi e il numero di occorrenze di ogni parola come valore, qui semplificato come:

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

quindi è possibile ottenere un elenco delle parole, ordinate per frequenza di utilizzo con sorted(d, key=d.get) - l'ordinamento itera sulle chiavi del dizionario, utilizzando il numero di occorrenze di parole come chiave di ordinamento.

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

Sto scrivendo questa spiegazione dettagliata per illustrare ciò che le persone spesso intendono con "Posso facilmente ordinare un dizionario per chiave, ma come faccio a ordinare per valore" - e penso che l'OP stia cercando di risolvere un problema del genere. E la soluzione è fare una sorta di elenco delle chiavi, in base ai valori, come mostrato sopra.


AGGIORNAMENTO: 5 DICEMBRE 2015 utilizzando Python 3.5

Anche se ho trovato la risposta accettata utile, sono stato anche sorpreso dal fatto che non è stato aggiornato per fare riferimento a OrderedDict dal modulo delle collezioni di librerie standard come un'alternativa valida e moderna - progettata per risolvere esattamente questo tipo di problema.

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

La documentazione ufficiale di OrderedDict offre anche un esempio molto simile, ma usando un lambda per la funzione sort:

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

Questo è il codice:

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

Ecco i risultati:

Originale

{'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}

Rango

{'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}

Se i valori sono numerici, puoi utilizzare anche Contatore dalle raccolte

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]    

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

Non è possibile ordinare un dizionario, solo per ottenere una rappresentazione di un dizionario che è ordinato. I dizionari sono intrinsecamente privi di ordine, ma altri tipi, come elenchi e tuple, non lo sono. Quindi è necessario un tipo di dati ordinato per rappresentare i valori ordinati, che sarà un elenco, probabilmente un elenco di tuple.

Per esempio,

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

sorted_x sarà una lista di tuple ordinate dal secondo elemento in ciascuna tupla. dict(sorted_x) == x .

E per coloro che desiderano ordinare le chiavi al posto dei valori:

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

In Python3 dal momento che la decompressione non è consentita [1] , possiamo usare

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

Usa ValueSortedDict da dicts :

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

Puoi usare le collections.Counter . Nota, questo funzionerà sia per valori numerici che non numerici.

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

Praticamente uguale alla risposta di Hank Gay;

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

O ottimizzato un po 'come suggerito da John Fouhy;

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


Nel recente Python 2.7, abbiamo il nuovo tipo OrderedDict , che ricorda l'ordine in cui sono stati aggiunti gli articoli.

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

Per creare un nuovo dizionario ordinato dall'originale, ordinando in base ai valori:

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

OrderedDict si comporta come un normale dettato:

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

I dadi non possono essere ordinati, ma è possibile creare un elenco ordinato da loro.

Un elenco ordinato di valori di dict:

sorted(d.values())

Un elenco di coppie (chiave, valore), ordinate per valore:

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

Prova il seguente approccio. Definiamo un dizionario chiamato mydict con i seguenti dati:

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

Se si volesse ordinare il dizionario per chiavi, si potrebbe fare qualcosa come:

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

Questo dovrebbe restituire il seguente risultato:

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

D'altra parte, se si volesse ordinare un dizionario per valore (come viene chiesto nella domanda), si potrebbe fare quanto segue:

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

Il risultato di questo comando (ordinando il dizionario per valore) dovrebbe restituire quanto segue:

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

Ecco una soluzione che utilizza zip su d.values() e d.keys() . Alcune linee in basso su questo collegamento (su Oggetti vista dizionario) sono:

Ciò consente la creazione di coppie (valore, chiave) usando zip (): pairs = zip (d.values ​​(), d.keys ()).

Quindi possiamo fare quanto segue:

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

Naturalmente, ricorda, devi usare OrderedDict perché i normali dizionari Python non mantengono l'ordine originale.

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

Se non hai Python 2.7 o versioni successive, il meglio che puoi fare è iterare sui valori in una funzione generatore. (C'è un OrderedDict per 2.4 e 2.6 here , ma

a) I don't know about how well it works 

e

b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option's out.)
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])

Puoi anche stampare ogni valore

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

Ricordarsi di rimuovere le parentesi dopo la stampa se non si utilizza Python 3.0 o successivo


Puoi usare la funzione ordinata di Python

sorted(iterable[, cmp[, key[, reverse]]])

Quindi puoi usare:

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

Visita questo link per maggiori informazioni sulla funzione ordinata: https://docs.python.org/2/library/functions.html#sorted


Puoi anche usare la funzione personalizzata che può essere passata alla chiave.

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)

Un altro modo per fare è usare la funzione labmda

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

Se i tuoi valori sono numeri interi e usi Python 2.7 o successivi, puoi usare collections.Counter invece di dict . Il metodo most_common ti fornirà tutti gli elementi, ordinati in base al valore.


Potresti usare:

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

Questo ordinerà il dizionario in base ai valori di ogni voce all'interno del dizionario dal più piccolo al più grande.


Spesso può essere molto utile usare namedtuple . Ad esempio, hai un dizionario di 'nome' come chiavi e 'punteggio' come valori e vuoi ordinare su 'punteggio':

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

ordinamento con il punteggio più basso prima:

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

ordinamento con il punteggio più alto prima:

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

Ora puoi ottenere il nome e il punteggio di, diciamo il secondo miglior giocatore (indice = 1) molto Pythonico come questo:

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

In Python 2.7, fai semplicemente:

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

copia-incolla da: http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

Godere ;-)


Questi parametri vengono in genere utilizzati per le funzioni proxy, pertanto il proxy può passare qualsiasi parametro di input alla funzione di destinazione.

def foo(bar=2, baz=5):
    print bar, baz

def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments
    print x
    foo(*args, **kwargs) # applies the "non-x" parameter to foo

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

Ma poiché questi parametri nascondono i nomi dei parametri effettivi, è meglio evitarli.





python sorting dictionary