【问题标题】:Length-wise-sorted list but, same length in alphabetical-order in a step按长度排序的列表,但在一个步骤中按字母顺序的长度相同
【发布时间】:2012-12-31 15:59:59
【问题描述】:

我的 Python 字符串列表类似于 x 但足够长:

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

我想将此列表排序为:['a', 'b', 'c', 'aa', 'ab', 'ba', 'aaa'],并且我在 两个 步骤中执行了以下操作:

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

但我需要一步到位:我还使用lambda 函数(taken help)绑定:

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

但不是我想要的:

可以一步到位吗?让我开心。

我的 Python:

~$ python --version  
Python 2.6.6

【问题讨论】:

  • 我将 python-2.7 标签编辑为 python-2.6,因为您明确声明您使用的是 2.6。

标签: python python-2.6


【解决方案1】:

你弄错了元组的顺序。当 Python 对元组进行排序时,第一个值是 main 排序,第二个是子排序,依此类推... - 您的代码假定相反的顺序。

你想按长度排序,然后按字母顺序:

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

编辑:正如 DSM 在 cmets 中指出的那样,Python 首先将字母排序为大写,然后是小写。如果不需要这种行为,请参阅this answer

【讨论】:

  • 由于大小写问题,这实际上并没有按字母顺序排序(但这很容易解决。)[我承认 OP 的列表目前都是小写的。]
  • @DSM 我正在​​模拟原始代码的行为 - 据说 - 工作代码,这可能是大写字母首先出现的错误,但这可能是所需的行为,目前尚不清楚。
  • @Lattyware :我的工作完成了,我明白了。但最后一个疑问。第一个两步解决方案如何工作?我按字母顺序排序然后长度!这就是我想不出你尝试了什么的原因..
  • 您的第一个解决方案有效,因为当 Python 对键进行排序并且值相等时,它会进行稳定排序 - 也就是说,相等值的顺序是它们在输入中的顺序。这意味着,如果您先按一个值排序,然后再按另一个值排序,第一个排序将通过作为子排序。
  • @Lattyware 我在 python 书中读了很多次这个术语stable sort 但我今天明白了意思.. 谢谢现在完全明白了。
【解决方案2】:

使用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

【讨论】:

  • 这似乎过于复杂了。没错,但是……我真的看不出它的价值。
  • 我喜欢itertools 和下一个家伙一样多,但这太疯狂了! PS:你不需要list 调用,sorted 将消耗g 并生成一个列表。
  • @DSM 忘记删除 list() 调用,将其用于测试目的。我知道与 lattyware 的答案相比,这是一种奇怪的方式,但在性能方面这更快。
  • @GrijeshChauhan 很高兴有帮助。
  • @AshwiniChaudhary 很好的模拟..这个能力非常好,需要..再次感谢!
猜你喜欢
  • 1970-01-01
  • 2013-09-24
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多