Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Length-wise-sorted list but, same length in alphabetical-order in a step

My Python List of string is something like x but long enough:

x = ['aaa','ab','aa','c','a','b','ba']      

I wants to sort this list as: ['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa'] and I did as follows in two steps:

>>> x.sort()   
>>> x.sort(key=len)      
>>> x
['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa']   

But I need in one-step: I also tied using lambda function (taken help):

>>> x.sort(key=lambda item: (item, len(item)))
>>> x
['a', 'aa', 'aaa', 'ab', 'b', 'ba', 'c']  

But not as I desired:

Is it possible in one-step? Please me.

My Python:

~$ python --version  
Python 2.6.6
like image 598
Grijesh Chauhan Avatar asked Dec 31 '12 15:12

Grijesh Chauhan


2 Answers

You got the order of the tuple the wrong way round. When Python sorts on tuples, the first value is the main sort, with the second being the subsort, etc... - your code presumes the opposite order.

You want to sort by length, then alphabetically:

>>> x.sort(key=lambda item: (len(item), item))
>>> x
['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa']

Edit: As DSM points out in the comments, Python sorts letters as capitals first, then lowercase. If this behaviour isn't wanted, see this answer.

like image 148
Gareth Latty Avatar answered Nov 16 '22 14:11

Gareth Latty


using itertools.grouby():

In [29]: lis = ['aaa','ab','aa','c','a','b','ba']
In [30]: list(chain(*[sorted(g) for k,g in groupby(sorted(lis,key=len),key=len)]))
Out[30]: ['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa']

timeit comparisons:

In [38]: x = ['aaa','ab','aa','c','a','b','ba']*1000

In [39]: random.shuffle(x)

#may be in more tricky test cases this would be fast

In [40]: %timeit sorted(x,key=lambda item: (len(item), item))
100 loops, best of 3: 11.3 ms per loop

In [41]: %timeit list(chain(*[sorted(g) for k,g in groupby(sorted(x,key=len),key=len)]))
100 loops, best of 3: 7.82 ms per loop
like image 1
Ashwini Chaudhary Avatar answered Nov 16 '22 15:11

Ashwini Chaudhary