Como todo el mundo ha señalado, los diccionarios tienen su propio ordenamiento y que no sólo puede ordenarlos como lo haría una lista.
Una cosa que me gustaría añadir es que, si lo que desea es ir a través de los elementos de un diccionario en forma ordenada, eso es sólo:
for k in sorted(a):
print k, a[k] # or whatever.
Si prefieres tener una lista por comprensión (por Alex):
sortedlist = [(k, a[k]) for k in sorted(a)]
me gustaría señalar que el uso de Alex de key=int
no funcionará con su ejemplo, porque una de sus claves es 'test'
. Si realmente desea que los números ordenados antes que los no-numéricos, que tendrá que pasar en una función 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 tal vez usted sabe lo suficiente acerca de sus claves para escribir una función para convertirlos en una cadena (u otro objeto) que ordena la derecha:
# 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.
Esto sería mucho más rápido que usar una función cmp
.
Realmente no me gusta tanto como las otras soluciones. '_keyify' es innecesariamente rígido y no creo que sea tan limpio como algunas de las otras soluciones y tu' _compare_keys' usa 'cmp', que generalmente es una mala señal. (También es una buena forma mantener los bloques 'try' para' try'/'except' lo más pequeño posible. Pondría' return' I {0: 0 {1}} '. Format (xi, MAX_DIGITS) 'en un 'else' block.) –
No, las soluciones no están optimizadas, solo están ahí como ejemplos o puntos de partida. (Es difícil sugerir una mejor solución sin saber cuál es el dominio clave real). Me gusta su solución, excepto la parte donde se rompe en Python 3. Originalmente escribí '_compare_keys' con dos bloques' try' de dos líneas, pero fue dos veces más largo. El uso de los bloques 'try' para controlar el flujo de ejecución eliminó la necesidad de un booleano' yint'. –
Supongo que quiere decir que usar el parámetro 'cmp', a diferencia de la función, es un" signo incorrecto ", y sí lo es, pero es provocado por el dominio clave incompletamente definido. Es por eso que seguí con la solución '_keyify'. Aún mejor sería crear una nueva clase para claves que pueda tomar una entrada de cadena y ordenarla correctamente, y usarla como la clave del diccionario, pero no sé si ben tiene tanto control sobre el diccionario de entrada. Y, sí, me olvidé de los bloques 'else'; demasiado C++ recientemente. Fijo. –