6

私のPythonの文字列リストは次のようなものですxが、十分な長さです。

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

このリストを次のように並べ替えたい と思います。2つのステップ ['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa']で次のようにしました。

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

しかし、私はワンステップで必要です:私はlambda関数を使用して結び付けました(助けを借りました):

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

しかし、私が望んでいたようではありません:

ワンステップで可能ですか?お願いします。

私のPython:

~$ python --version  
Python 2.6.6
4

2 に答える 2

9

タプルの順序が間違っています。Pythonがタプルでソートする場合、最初の値がメインソートで、2番目の値がサブソートなどです。コードは逆の順序を想定しています。

長さで並べ替えてからアルファベット順に並べ替えます。

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

編集:DSMがコメントで指摘しているように、Pythonは文字を最初に大文字としてソートし、次に小文字としてソートします。この動作が望ましくない場合は、この回答を参照してください。

于 2012-12-31T16:01:07.470 に答える
1

使用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比較:

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
于 2012-12-31T16:19:11.380 に答える