2011-01-14 7 views
14

у меня есть настройки питонов словаря как такСортировка ключей словаря на основе их значений

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

мне нужно написать функцию, которая возвращает упорядоченные ключи в списке, в зависимости от того, какого столбца вашей сортировки так, например, если мы сортировка mydict [ключ] [1] (по возрастанию)

я должен получить список назад, как так

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

в основном это работает, кроме, когда у вас есть столбцы одного и та же в lue для нескольких ключей, например. 'a2': ['e', 2] и 'a4': ['s', 2]. В этом случае она возвращает список как так

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

Вот функция я определил

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 

И если я хочу, чтобы отсортировать по столбцу чисел, например, это называется как так

sortedkeysasc = itmethods.itlist(table,2) 

Итак, любые предложения?

Пол

+0

вам просто нужно использовать 'key' kwarg функции сортировки – ulidtko

ответ

36

Не было бы намного проще в использовании

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

d является словарем)?

+0

Гладкий, +1. И это возвращает список по желанию. – user225312

+0

Да, и ленивость итератора особенно полезна. Это решение лучше, чем мое, жаль, что я не могу увеличить дважды%) – ulidtko

+0

@ulidtko: lazines не имеет особого значения, так как 'sorted()' будет генерировать весь список перед сортировкой в ​​любом случае. Это было бы эквивалентно использованию 'a = d.keys(); a.sort (key = lambda k: d [k] [1]) 'здесь, но' sorted (d.keys(), ...) 'создаст избыточную копию списка. –

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

Здесь сортировать словарные элементы (пары ключ-значение), используя ключ - отозваны, который устанавливает общий порядок по пунктам.

Затем вы просто отфильтровываете необходимые значения, используя map с lambda, который просто выбирает ключ. Таким образом, вы получаете необходимый список ключей.


EDIT: см this answer для гораздо лучшее решение.

+3

я несколько пристрастен к' [к для (к, v) в отсортированный (...)] 'а. –

+0

Blimey очень приятно спасибо! Гораздо меньше кода, чем мое решение! – 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

Хотя существует несколько рабочих ответов выше, небольшое изменение/комбинация из них является наиболее вещий мне:

[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'] 
Смежные вопросы