Come chiunque altro ha sottolineato, dizionari hanno un proprio ordinamento e non si può semplicemente ordinarli come si farebbe un elenco.
Una cosa che vorrei aggiungere è che, se si desidera solo per passare attraverso gli elementi di un dizionario in ordine sequenziale, questo è solo:
for k in sorted(a):
print k, a[k] # or whatever.
Se si preferisce avere una lista di comprensione (per Alex):
sortedlist = [(k, a[k]) for k in sorted(a)]
vorrei far notare che l'uso di Alex di key=int
non funziona con il vostro esempio perché una delle chiavi è 'test'
. Se si vuole veramente che i numeri ordinati prima che i non-numerici, si dovrà passare in una funzione cmp
:
def _compare_keys(x, y):
try:
x = int(x)
except ValueError:
xint = False
else:
xint = True
try:
y = int(y)
except ValueError:
if xint:
return -1
return cmp(x.lower(), y.lower())
# or cmp(x, y) if you want case sensitivity.
else:
if xint:
return cmp(x, y)
return 1
for k in sorted(a, cmp=_compare_keys):
print k, a[k] # or whatever.
O forse si sa abbastanza circa le chiavi per scrivere una funzione per convertirli in una stringa (o un altro oggetto) che ordina a destra:
# Won't work for integers with more than this many digits, or negative integers.
MAX_DIGITS = 10
def _keyify(x):
try:
xi = int(x)
except ValueError:
return 'S{0}'.format(x)
else:
return 'I{0:0{1}}'.format(xi, MAX_DIGITS)
for k in sorted(a, key=_keyify):
print k, a[k] # or whatever.
Questo sarebbe molto più veloce rispetto all'utilizzo di una funzione cmp
.
Non mi piace tanto quanto le altre soluzioni. '_keyify' è inutilmente rigido e non penso sia così pulito come alcune delle altre soluzioni e il tuo' _compare_keys' usa 'cmp', che di solito è un brutto segno. (È anche una buona forma tenere i blocchi 'try' per' try'/'except' il più piccolo possibile.Porrei mettere' return 'I {0: 0 {1}}.. Format (xi, MAX_DIGITS) 'in un 'else' block.) –
No, le soluzioni non sono ottimizzate, sono solo lì come esempi o punti di partenza. (È difficile suggerire una soluzione migliore senza sapere quale sia il vero dominio della chiave.) Mi piace la tua soluzione eccetto per la parte in cui si rompe in Python 3. Originariamente ho scritto '_compare_keys' con due blocchi' try' a due righe, ma era il doppio del tempo. L'utilizzo dei blocchi 'try' per controllare il flusso di esecuzione ha eliminato la necessità di un booleano' yint'. –
Suppongo che tu intenda che usare il parametro 'cmp', al contrario della funzione, sia un" cattivo segno ", e sì lo è, ma è causato dal dominio della chiave completamente definito. Ecco perché ho seguito la soluzione '_keyify'. Sarebbe anche meglio creare una nuova classe per le chiavi che possano prendere un input di stringa e ordinarlo correttamente, e usarlo come chiave del dizionario, ma non so se ben ha il controllo sul dizionario di input. E, sì, mi sono dimenticato dei blocchi 'else'; troppo C++ di recente. Fisso. –