2011-01-14 15 views
14

Tengo una configuración diccionario de Python como talOrdenación de las claves de diccionario basado en sus valores

mydict = { 'a1': ['g',6], 
      'a2': ['e',2], 
      'a3': ['h',3], 
      'a4': ['s',2], 
      'a5': ['j',9], 
      'a6': ['y',7] } 

Tengo que escribir una función que devuelve las llaves ordenados en una lista, en función de la columna de su clasificación en lo que por ejemplo si estamos en la clasificación mydict [clave] [1] (ascendente)

que debería recibir una lista de vuelta al igual que

['a2', 'a4', 'a3', 'a1', 'a6', 'a5'] 

en su mayoría se trabaja, además de cuando se tiene columnas de la misma VA lue para llaves múltiples, ej. 'a2': ['e', 2] y 'a4': ['s', 2]. En este caso se devuelve la lista al igual que

['a4', 'a4', 'a3', 'a1', 'a6', 'a5'] 

Ésta es la función he definido

def itlist(table_dict,column_nb,order="A"): 
    try: 
     keys = table_dict.keys() 
     values = [i[column_nb-1] for i in table_dict.values()] 
     combo = zip(values,keys) 
     valkeys = dict(combo) 
     sortedCols = sorted(values) if order=="A" else sorted(values,reverse=True) 
     sortedKeys = [valkeys[i] for i in sortedCols] 
    except (KeyError, IndexError), e: 
     pass 
    return sortedKeys 

Y si quiero ordenar en la columna de números, por ejemplo, que se llama así por lo

sortedkeysasc = itmethods.itlist(table,2) 

¿Alguna sugerencia?

Paul

+0

sólo tiene que utilizar el 'key' kwarg de la función de clasificación – ulidtko

Respuesta

36

¿No sería mucho más fácil de usar

sorted(d, key=lambda k: d[k][1]) 

(con d siendo el diccionario)?

+0

Elegante, +1. Y esto devuelve una lista como se desee. – user225312

+0

Sí, y la pereza del iterador es particularmente una ventaja también. Esta solución es mejor que la mía, lástima que no puedo votar dos veces%) – ulidtko

+0

@ulidtko: Los lazines no son particularmente relevantes, ya que 'sorted()' generará toda la lista antes de ordenar de todos modos. Sería equivalente a usar 'a = d.keys(); a.sort (clave = lambda k: d [k] [1]) 'aquí, pero' ordenado (d.keys(), ...) 'crearía una copia redundante de la lista. –

9
>>> L = sorted(d.items(), key=lambda (k, v): v[1]) 
>>> L 
[('a2', ['e', 2]), ('a4', ['s', 2]), ('a3', ['h', 3]), ('a1', ['g', 6]), ('a6', ['y', 7]), ('a5', ['j', 9])] 

>>> map(lambda (k,v): k, L) 
['a2', 'a4', 'a3', 'a1', 'a6', 'a5'] 

Aquí ordenar los elementos del diccionario (pares clave-valor) utilizando una llave - exigible que establece un orden total de los artículos.

Luego, solo filtra los valores necesarios usando un map con un lambda que simplemente selecciona la clave. Entonces obtienes la lista de llaves necesaria.


EDIT: ver this answer para una solución mucho mejor.

+3

estoy un poco parcial a' [k de (k, v) en la ordenada (...)] 'también. –

+0

Blimey muy agradable gracias! Mucho menos código que mi solución también! – PDStat

0
def itlist(table_dict, col, desc=False): 
    return [key for (key,val) in 
     sorted(
      table_dict.iteritems(), 
      key=lambda x:x[1][col-1], 
      reverese=desc, 
      ) 
     ] 
3

Aunque hay múltiples respuestas de trabajo anterior, una variación leve/combinación de ellos es el más Pythonic a mí:

[k for (k,v) in sorted(mydict.items(), key=lambda (k, v): v[1])] 
0
>>> mydict = { 'a1': ['g',6], 
...   'a2': ['e',2], 
...   'a3': ['h',3], 
...   'a4': ['s',2], 
...   'a5': ['j',9], 
...   'a6': ['y',7] } 
>>> sorted(mydict, key=lambda k:mydict[k][1]) 
['a2', 'a4', 'a3', 'a1', 'a6', 'a5'] 
>>> sorted(mydict, key=lambda k:mydict[k][0]) 
['a2', 'a1', 'a3', 'a5', 'a4', 'a6'] 
Cuestiones relacionadas