简体   繁体   中英

sorting values of python dict using sorted builtin function

I need to get a sorted representation of a dict ,sorted in the descending order of values (largest value in dict to be shown first).

sample:

mydict={u'jon':30,u'den':26,u'rob':42,u'jaime':31}

I need to show them like

rob=42
jaime=31
jon=30
den=28

I tried this

from operator import itemgetter
sortedvalues=sorted(mydict,key=itemgetter(1))

When I print the list I get

[u'jaime', u'den', u'rob', u'jon']

This list is unordered! Am I missing something about the usage of sorted builtin ? or am I using the itemgetter incorrectly?

This is an interesting problem because you didn't cause an error like you would have if the keys were of another non-indexable type (say integers), and this is due to a subtle series of things:

  1. sorted(mydict, ...) tries to iterate a dictionary using the equivalent of iter(mydict) which will call mydict.__iter__()
  2. Iterating a dictionary yields its keys , in effect iter(mydict) is the same as mydict.iterkeys() .
  3. Your keys were strings, and since strings are indexable, itemgetter(1) will work on a string value, getting the second character in the string.

The code you had would've failed with an IndexError if any strings had a 1-char length as well, you just lucked by. (or didn't, depending on how you look at it, since getting the IndexError would've made you aware of the problem sooner.)

What you want to do if you only want the values is:

sorted(mydict.values(), reverse=True)

And if you want the keys as well in pairs, you want

sorted(mydict.iteritems(), key=itemgetter(1), reverse=True)

They're sorted by the second letter in the name; iterating over a dict yields its keys.

sorteditems = sorted(mydict.iteritems(), key=itemgetter(1))

Iterating over a dictionary (which is what the sorted function does) will give you only it's keys:

>>> sorted(mydict)
[u'den', u'jaime', u'jon', u'rob']

Instead you want to sort both the keys and values - to do this, you would use mydict.items() (or mydict.iteritems() , which is more efficient with large dicts):

>>> sorted(mydict.items())
[(u'den', 26), (u'jaime', 31), (u'jon', 30), (u'rob', 42)]

Then your code would work as expected:

>>> from operator import itemgetter
>>> sorted(mydict.items(), key = itemgetter(1))
[(u'den', 26), (u'jon', 30), (u'jaime', 31), (u'rob', 42)]

You may also want to sort with the dict's key as the secondary sort value, in case multiple keys have the same value:

>>> mydict={u'a': 1, 'z': 1, 'd': 1}
>>> sorted(mydict.items(), key = itemgetter(1))
[(u'a', 1), ('z', 1), ('d', 1)]
>>> sorted(mydict.items(), key = itemgetter(1, 0))
[(u'a', 1), ('d', 1), ('z', 1)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM