2011-01-14 20 views
14

Mam konfiguracji słownika Python podobnie jakSortowanie klucze słownika w oparciu o ich wartości

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

muszę napisać funkcję, która zwraca zamówionych kluczy na liście, w zależności od kolumny swój sortowanie tak na przykład jeśli mamy do sortowania na mydict [key] [1] (rosnąco)

powinienem otrzymać listę z powrotem jak tak

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

To głównie działa, oprócz kiedy masz kolumny o tej samej va Lue dla wielu kluczy, np. "a2": ["e", 2] i "a4": ["s", 2]. W tym przypadku zwraca lista jak tak

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

Oto funkcja Mam zdefiniowane

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 

A jeśli chcę, aby posortować kolumny liczb, na przykład nazywa jak tak

sortedkeysasc = itmethods.itlist(table,2) 

Jakieś sugestie?

Paul

+0

wystarczy użyć 'key' kwarg funkcji sortowania – ulidtko

Odpowiedz

36

nie byłoby o wiele łatwiejsze w użyciu

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

(z językiem d)?

+0

Elegancki, +1. A to zwraca listę według życzenia. – user225312

+0

Tak, a lenistwo iteratora jest szczególnie korzystne. To rozwiązanie jest lepsze niż moje, szkoda, że ​​nie mogę dwukrotnie zająć się%). – ulidtko

+0

@ulidtko: Lazynia nie ma szczególnego znaczenia, ponieważ 'sorted()' wygeneruje całą listę przed sortowaniem. Byłoby to równoważne użyciu 'a = d.keys(); a.sort (key = lambda k: d [k] [1]) 'tutaj, ale' posortowane (d.keys(), ...) 'utworzyłoby redundantną kopię listy. –

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

Tutaj sortowania słownika elementy (par klucz-wartość) przy użyciu klucz - wywoływalnym który ustanawia całkowity porządek na pozycje.

Następnie odfiltrowuje się potrzebne wartości za pomocą map z lambda, który właśnie wybiera klucz. Dostajesz więc potrzebną listę kluczy.


EDIT: zobaczyć this answer na o wiele lepsze rozwiązanie.

+3

jestem nieco częściowym' [K dla (k, v) w sortowane (...)] ', jak również. –

+0

Blimey bardzo miły dzięki! Znacznie mniej kodu niż moje rozwiązanie! – 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

Chociaż istnieje wiele odpowiedzi robocze powyżej, niewielka zmienność/połączenie z nich jest najbardziej pythonic do mnie:

[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'] 
Powiązane problemy