How to specify 2 keys in python sorted(list)?

2019-02-21 08:07发布

How do I sort a list of strings by key=len first then by key=str? I've tried the following but it's not giving me the desired sort:

>>> ls = ['foo','bar','foobar','barbar']
>>> 
>>> for i in sorted(ls):
...     print i
... 
bar
barbar
foo
foobar
>>>
>>> for i in sorted(ls, key=len):
...     print i
... 
foo
bar
foobar
barbar
>>> 
>>> for i in sorted(ls, key=str):
...     print i
... 
bar
barbar
foo
foobar

I need to get:

bar
foo
barbar
foobar

4条回答
爷、活的狠高调
2楼-- · 2019-02-21 08:33

If you don't want to use lambda:

from operator import itemgetter
ls = ['foo','bar','foobar','barbar']
print sorted([ [x,len(x)] for x in ls ] ,key=itemgetter(1,0))
# print [s[0] for s in sorted([ [x,len(x)] for x in ls ] ,key=itemgetter(1,0))]
查看更多
三岁会撩人
3楼-- · 2019-02-21 08:39

Define a key function that returns a tuple in which the first item is len(str) and the second one is the string itself. Tuples are then compared lexicographically. That is, first the lengths are compared; if they are equal then the strings get compared.

In [1]: ls = ['foo','bar','foobar','barbar']

In [2]: sorted(ls, key=lambda s: (len(s), s))
Out[2]: ['bar', 'foo', 'barbar', 'foobar']
查看更多
时光不老,我们不散
4楼-- · 2019-02-21 08:46

Another form that works without a lambda:

>>> [t[1] for t in sorted((len(s),s) for s in ls)]
['bar', 'foo', 'barbar', 'foobar']
查看更多
The star\"
5楼-- · 2019-02-21 08:48

The answer from root is correct, but you don't really need a lambda:

>>> def key_function(x):
        return len(x), str(x)

>>> sorted(['foo','bar','foobar','barbar'], key=key_function)
['bar', 'foo', 'barbar', 'foobar']

In addtion, there is a alternate approach takes advantage of sort stability which lets you sort in multiple passes (with the secondary key first):

>>> ls = ['foo','bar','foobar','barbar']
>>> ls.sort(key=str)                       # secondary key
>>> ls.sort(key=len)                       # primary key

See the Sorting HOWTO for a good tutorial on Python sorting techniques.

查看更多
登录 后发表回答