Domanda

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 le chiavi, ma come posso ordinare in base ai valori?

Nota: ho letto la domanda Stack Overflow qui Come posso ordinare un elenco di dizionari in base al valore del dizionario? e probabilmente potrei 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 per ordinare in ordine crescente o decrescente.

È stato utile?

Soluzione

Non è possibile ordinare un dizionario, solo per ottenere una rappresentazione di un dizionario ordinato. I dizionari sono intrinsecamente senza 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.

Ad esempio,

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

sort_x sarà un elenco di tuple ordinate per secondo elemento in ciascuna tupla. dict (sort_x) == x .

E per coloro che desiderano ordinare le chiavi anziché i 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 poiché il disimballaggio non è consentito [1] possiamo usare

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

Se vuoi l'output come dict, puoi usare collections.OrderedDict :

import collections

sorted_dict = collections.OrderedDict(sorted_x)

Altri suggerimenti

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

Bene, in realtà è possibile fare un "ordinamento per valori di dizionario". Recentemente ho dovuto farlo in un Code Golf (domanda Stack Overflow Golf golf: Grafico della frequenza delle parole ). Abbreviato, il problema era del tipo: dato un testo, conta la frequenza con cui ogni parola viene incontrata e visualizza 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, semplificato qui come:

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

quindi puoi ottenere un elenco delle parole, ordinate per frequenza d'uso con ordinato (d, chiave = d.get) - l'ordinamento scorre tra le chiavi del dizionario, usando il numero di parole occorrenze 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 per " Posso facilmente ordinare un dizionario per chiave, ma come posso ordinare per valore " - e penso che l'OP stesse cercando di affrontare un simile problema. E la soluzione è fare una sorta di elenco delle chiavi, in base ai valori, come mostrato sopra.

Puoi usare:

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

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

Per ordinarlo in ordine decrescente basta aggiungere reverse = True :

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

I Dicts non possono essere ordinati, ma è possibile creare un elenco ordinato da essi.

Un elenco ordinato di valori dict:

sorted(d.values())

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

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

Nel recente Python 2.7, abbiamo il nuovo 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, ordinandolo 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 dict:

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

AGGIORNAMENTO: 5 DICEMBRE 2015 utilizzando Python 3.5

Mentre ho trovato utile la risposta accettata, sono rimasto sorpreso anche dal fatto che non è stato aggiornato per fare riferimento a OrderedDict dal modulo della libreria standard collezioni come 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)])

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

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

Praticamente uguale a Risposta di Hank Gay :

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

O leggermente ottimizzato come suggerito da John Fouhy:

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

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

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

ordinamento per primo con il punteggio più basso:

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

ordinamento per primo con il punteggio più alto:

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

Ora puoi ottenere il nome e il punteggio di, diciamo che il secondo miglior giocatore (indice = 1) in questo modo molto pitonicamente:

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

A partire da Python 3.6 verrà ordinato il dict incorporato

Buone notizie, quindi il caso d'uso originale del PO di coppie di mapping recuperate da un database con ID stringa univoci come chiavi e valori numerici come valori in un dict Python v3.6 + integrato, ora dovrebbe rispettare l'ordine di inserimento.

Se dicono le risultanti espressioni della tabella di due colonne da una query del database come:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

verrebbe memorizzato in due tuple Python, k_seq e v_seq (allineate per indice numerico e con la stessa lunghezza del corso), quindi:

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

Consenti output in seguito come:

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

cedendo in questo caso (per il nuovo dict incorporato di Python 3.6+!):

foo 0
bar 1
baz 42

nello stesso ordine per valore di v.

Dove nell'installazione di Python 3.5 sul mio computer attualmente risulta:

bar 1
foo 0
baz 42

dettagli:

Come proposto nel 2012 da Raymond Hettinger (vedi mail su python-dev con soggetto " Dizionari più compatti con iterazione più veloce " ) e ora (nel 2016) annunciato in una mail di Victor Stinner a python-dev con oggetto " Python 3.6 dict diventa compatto e ottiene una versione privata; e le parole chiave vengono ordinate " a causa della correzione / implementazione del problema 27350 " Compatto e ordinato dict " in Python 3.6 ora saremo in grado di usare un dict incorporato per mantenere l'ordine di inserimento !!

Speriamo che questo porti a un'implementazione di OrderedDict a livello sottile come primo passo. Come indicato da @ JimFasarakis-Hilliard, alcuni vedranno casi d'uso per il tipo OrderedDict anche in futuro. Penso che la comunità di Python in generale esaminerà attentamente, se questo resisterà alla prova del tempo e quali saranno i prossimi passi.

È ora di ripensare alle nostre abitudini di codifica per non perdere le possibilità aperte da un ordinamento stabile di:

  • Argomenti delle parole chiave e
  • archiviazione (intermedia) dict

Il primo perché facilita l'invio nell'implementazione di funzioni e metodi in alcuni casi.

Il secondo in quanto incoraggia a utilizzare più facilmente dict come memoria intermedia nelle pipeline di elaborazione.

Raymond Hettinger ha gentilmente fornito la documentazione che spiega " La tecnologia Behind Python 3.6 Dictionaries " - dalla presentazione del gruppo Meetup di San Francisco Python 2016-DEC-08.

E forse alcune pagine di domande e risposte decorate con Stack Overflow riceveranno varianti di queste informazioni e molte risposte di alta qualità richiedono anche un aggiornamento per versione.

Caveat Emptor (ma vedi anche di seguito aggiornamento 15-12-2017):

Come giustamente osserva @ajcr: "L'aspetto che preserva l'ordine di questa nuova implementazione è considerato un dettaglio dell'implementazione e non dovrebbe essere invocato." (dal whatsnew36 ) non picking nit, ma la citazione è stata un po 'pessimista ;-). Continua come " (questo potrebbe cambiare in futuro, ma si desidera avere questa nuova implementazione di dict nella lingua per alcune versioni prima di modificare le specifiche della lingua per imporre la semantica di conservazione dell'ordine per tutte le implementazioni Python attuali e future; questo aiuta anche a preservare all'indietro- compatibilità con le versioni precedenti della lingua in cui l'ordine di iterazione casuale è ancora in vigore, ad esempio Python 3.5). "

Come in alcune lingue umane (ad esempio il tedesco), l'utilizzo modella la lingua e la volontà è stata dichiarata ... in whatsnew36 .

Aggiornamento 15/12/2017:

In una posta nell'elenco python-dev , Ha dichiarato Guido van Rossum:

  

Rendilo così. " Dict mantiene l'ordine di inserimento " è la sentenza. Grazie!

Quindi, l'effetto collaterale CPython versione 3.6 dell'ordine di inserimento di dict ora sta diventando parte delle specifiche del linguaggio (e non più solo un dettaglio di implementazione). Quel thread di posta emerse anche alcuni obiettivi di design distintivi per collezioni.OrderedDict come ricordato da Raymond Hettinger durante la discussione.

Ho avuto lo stesso problema e l'ho risolto in questo modo:

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

(Le persone che rispondono a "non è possibile ordinare un dict" non hanno letto la domanda! In effetti, "posso ordinare sulle chiavi, ma come posso ordinare in base ai valori?" che desidera un elenco delle chiavi ordinate in base al valore dei loro valori.)

Si noti che l'ordine non è ben definito (le chiavi con lo stesso valore saranno in un ordine arbitrario nell'elenco di output).

In Python 2.7, 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-esempi-e-ricette

Divertiti ;-)

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:

Original

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

Classifica

{'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 anche utilizzare Counter dalle collezioni .

from collections import Counter

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

>> [('python', 5), ('world', 3), ('hello', 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 in base alle chiavi, si potrebbe fare qualcosa del tipo:

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

Questo dovrebbe restituire il seguente output:

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

D'altra parte, se si volesse ordinare un dizionario per valore (come richiesto 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 (ordinamento del dizionario per valore) dovrebbe restituire quanto segue:

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

Puoi creare un " indice invertito " ;, anche

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

Ora il tuo inverso ha i valori; ogni valore ha un elenco di chiavi applicabili.

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

Puoi utilizzare le collections.Counter . Nota, questo funzionerà con valori sia 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)])

A partire da Python 3.6, gli oggetti dict sono ora ordinati per ordine di inserzione. È ufficialmente nelle specifiche di 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}

Prima di allora, dovevi usare OrderedDict .

Documentazione di Python 3.7 dice:

  

Modificato nella versione 3.7: l'ordine del dizionario è garantito per l'inserimento   ordine. Questo comportamento era il dettaglio dell'implementazione di CPython dalla 3.6.

Puoi utilizzare un skip dict che è un dizionario che è ordinato in modo permanente per valore.

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

Se usi chiavi () , valori () o items () , eseguirai l'ordinamento in ordine di valore.

È implementato utilizzando la skip list struttura dati.

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

Puoi anche usare una 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)

Come sottolineato da Dilettant , Python 3.6 ora manterrà l'ordine ! Ho pensato di condividere una funzione che ho scritto che facilita l'ordinamento di un iterabile (tupla, elenco, dict). In quest'ultimo caso, è possibile ordinare in base a chiavi o valori e può tenere conto del confronto numerico. Solo per > = 3.6!

Quando provi a utilizzare l'ordinamento su un iterabile che contiene ad es. stringhe e ints, sort () falliranno. Ovviamente puoi forzare il confronto delle stringhe con str (). Tuttavia, in alcuni casi si desidera eseguire un confronto effettivo in cui 12 è inferiore a 20 (che non è il caso nel confronto tra stringhe). Quindi ho pensato a quanto segue. Quando si desidera un confronto numerico esplicito, è possibile utilizzare il flag num_as_num che tenterà di eseguire l'ordinamento numerico esplicito tentando di convertire tutti i valori in float. Se ciò ha esito positivo, eseguirà l'ordinamento numerico, altrimenti ricorrerà al confronto delle stringhe.

Commenti di miglioramento o richieste push benvenuto.

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

Ecco una soluzione che utilizza zip su d. valori () e d.keys () . Alcune righe lungo questo link (sugli oggetti della vista Dizionario) sono:

  

Ciò consente la creazione di coppie (valore, chiave) usando zip (): coppie = 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')]

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

Scorrere un dict e ordinarlo in base al valore 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

Se i tuoi valori sono numeri interi e utilizzi Python 2.7 o versioni successive, puoi utilizzare collections.Counter anziché dict . Il metodo most_common ti darà tutti gli elementi, ordinati per valore.

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 si dispone di Python 2.7 o versioni successive, il meglio che si può fare è scorrere i valori in una funzione del generatore. (Esiste un OrderedDict per 2.4 e 2.6 qui , ma

a) Non so quanto funzioni bene

e

b) Ovviamente devi scaricarlo e installarlo. Se non hai accesso amministrativo, temo che l'opzione sia disattivata.)


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

Funziona in 3.1.x:

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

Per completezza, sto pubblicando una soluzione utilizzando heapq . Nota, questo metodo funzionerà con valori sia numerici che non numerici

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

Ho appena appreso le abilità pertinenti da Python per tutti .

Puoi utilizzare un elenco temporaneo per aiutarti a ordinare il dizionario:

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

Se si desidera ordinare l'elenco in ordine decrescente, modificare semplicemente la riga di ordinamento originale in:

tmp = sorted(tmp, reverse=True)

Usando la comprensione dell'elenco, l'unica riga sarebbe:

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

Output di esempio:

#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')]
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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top