我有一套
set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
排序后,我希望它看起来像
4 sheets,
12 sheets,
48 sheets,
booklet
有什么想法吗
Answers:
简短而甜美:
sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
这个版本:
cmp
参数sorted
(Python 3中不存在)如果要完全按照示例中的说明打印输出,则:
data = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
r = sorted(data, key=lambda item: (int(item.partition(' ')[0])
if item[0].isdigit() else float('inf'), item))
print ',\n'.join(r)
杰夫·阿特伍德(Jeff Atwood)讨论了自然排序,并举例说明了使用Python进行排序的一种方法。这是我的变化形式:
import re
def sorted_nicely( l ):
""" Sort the given iterable in the way that humans expect."""
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
像这样使用:
s = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
for x in sorted_nicely(s):
print(x)
输出:
4 sheets
12 sheets
48 sheets
booklet
此方法的一个优点是,当字符串之间用空格分隔时,该方法不仅有效。它还适用于其他分隔符,例如版本号中的句点(例如1.9.1在1.10.0之前)。
[('b', 0), ('0', 1), ('a', 2)]
分类为[('0', 1), ('a', 2), ('b', 0)]
.lower()
到key
中re.split
。
有人建议我在这里重新发布此答案,因为它在这种情况下也很好用
from itertools import groupby
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby(s, str.isdigit)]
sorted(my_list, key=keyfunc)
演示:
>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
对于Python3,有必要对其进行一些修改(此版本在Python2中也可以正常使用)
def keyfunc(s):
return [int(''.join(g)) if k else ''.join(g) for k, g in groupby('\0'+s, str.isdigit)]
通用答案,用于对字符串数组中任何位置的任何数字进行排序。适用于Python 2和3。
def alphaNumOrder(string):
""" Returns all numbers on 5 digits to let sort the string with numeric order.
Ex: alphaNumOrder("a6b12.125") ==> "a00006b00012.00125"
"""
return ''.join([format(int(x), '05d') if x.isdigit()
else x for x in re.split(r'(\d+)', string)])
样品:
s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5']
s.sort(key=alphaNumOrder)
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1']
答案的一部分来自那里
集本质上是无序的。您需要创建一个具有相同内容的列表并对其进行排序。
对于那些使用2.4之前版本的Python却没有出色sorted()
功能的人来说,一种快速排序集的方法是:
l = list(yourSet)
l.sort()
这不能回答上面的特定问题(12 sheets
将在之前出现4 sheets
),但对来自Google的人可能有用。
4a sheets
但谁在乎呢?要解决此问题,您需要一个实函数而不是lambda。