PDStat
PDStat

Reputation: 5825

Sorting dictionary keys based on their values

I have a python dictionary setup like so

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

I need to write a function which returns the ordered keys in a list, depending on which column your sorting on so for example if we're sorting on mydict[key][1] (ascending)

I should receive a list back like so

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

It mostly works, apart from when you have columns of the same value for multiple keys, eg. 'a2': ['e',2] and 'a4': ['s',2]. In this instance it returns the list like so

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

Here's the function I've defined

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

And if I want to sort on the numbers column for example it is called like so

sortedkeysasc = itmethods.itlist(table,2)

So any suggestions?

Paul

Upvotes: 22

Views: 36614

Answers (5)

Sven Marnach
Sven Marnach

Reputation: 601609

Wouldn't it be much easier to use

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

(with d being the dictionary)?

Upvotes: 57

ulidtko
ulidtko

Reputation: 15560

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

Here you sort the dictionary items (key-value pairs) using a key - callable which establishes a total order on the items.

Then, you just filter out needed values using a map with a lambda which just selects the key. So you get the needed list of keys.


EDIT: see this answer for a much better solution.

Upvotes: 10

John La Rooy
John La Rooy

Reputation: 304167

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

Upvotes: 2

Kimvais
Kimvais

Reputation: 39548

Although there are multiple working answers above, a slight variation / combination of them is the most pythonic to me:

[k for (k,v) in sorted(mydict.items(), key=lambda (k, v): v[1])]

Upvotes: 3

Amber
Amber

Reputation: 526613

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,
            )
        ]

Upvotes: 0

Related Questions