如何最简单地对一个以数字结尾的字符串列表进行排序,其中有一些字符串末尾是三位数字,另一些是四位数字:
>>> list = ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
>>> list.sort()
>>> print list
['asdf111', 'asdf123', 'asdf1234', 'asdf124']
应该把1234放在最后,有没有简单的方法可以做到这一点?
如何最简单地对一个以数字结尾的字符串列表进行排序,其中有一些字符串末尾是三位数字,另一些是四位数字:
>>> list = ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
>>> list.sort()
>>> print list
['asdf111', 'asdf123', 'asdf1234', 'asdf124']
应该把1234放在最后,有没有简单的方法可以做到这一点?
有没有简单的方法做到这一点?
是的。
您可以使用natsort模块。
>>> from natsort import natsorted
>>> natsorted(['asdf123', 'asdf1234', 'asdf111', 'asdf124'])
['asdf111', 'asdf123', 'asdf124', 'asdf1234']
完全透明,我是该软件包的作者。
有没有简单的方法做到这点?
没有。
真正的规则并不清楚。"一些有三位数字,一些有四位数字"并不是非常精确或完整的说明。所有的例子都在数字前面有四个字母。这总是正确的吗?
import re
key_pat = re.compile(r"^(\D+)(\d+)$")
def key(item):
m = key_pat.match(item)
return m.group(1), int(m.group(2))
key
函数可能能够满足您的需求。或者它可能过于复杂。或者也许模式实际上是 r"^(.*)(\d{3,4})$"
,或者规则甚至更加难懂。>>> data= ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
>>> data.sort( key=key )
>>> data
['asdf111', 'asdf123', 'asdf124', 'asdf1234']
.sort
函数带有函数参数是一个非常有用的技巧,值得掌握。谢谢。 - Hope>>> 'a1234' < 'a124' <----- positionally '3' is less than '4'
True
>>>
>>> x = ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
>>> y = [ int(t[4:]) for t in x]
>>> z = sorted(y)
>>> z
[111, 123, 124, 1234]
>>> l = ['asdf'+str(t) for t in z]
>>> l
['asdf111', 'asdf123', 'asdf124', 'asdf1234']
>>>
l = ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
l.sort(cmp=lambda x,y:cmp(int(x[4:]), int(y[4:]))
key
自2.4以来就一直存在,而cmp
已被弃用并在3.x版中被删除。我真的不知道为什么类似这样的垃圾代码会得到两个赞。它甚至不能比较其余的字符串。 - aaronasterlingsort
函数的reverse
关键字参数来进行排序时的反转。 - SethMMorton你需要一个关键函数。你愿意在末尾指定3或4个数字,我有一种感觉你想要它们进行数值比较。
sorted(list_, key=lambda s: (s[:-4], int(s[-4:])) if s[-4] in '0123456789' else (s[:-3], int(s[-3:])))
没有 lambda 和条件表达式的话,那就……
def key(s):
if key[-4] in '0123456789':
return (s[:-4], int(s[-4:]))
else:
return (s[:-3], int(s[-3:]))
sorted(list_, key=key)
这只是利用元组按第一个元素,然后按第二个元素排序的事实。因此,由于调用key
函数以获取要比较的值,因此现在将像键函数返回的元组一样比较元素。例如,'asdfbad123'
将与'asd7890'
进行比较,如('asdfbad',123)
与('asd',7890)
进行比较。如果字符串的最后3个字符实际上不是数字,则会引发ValueError,这是完全适当的,因为您传递给它的数据不符合其设计规格。
不是自己分割每一行,而是使用 re.findall()
让 Python 为我完成:
import re
import sys
def SortKey(line):
result = []
for part in re.findall(r'\D+|\d+', line):
try:
result.append(int(part, 10))
except (TypeError, ValueError) as _:
result.append(part)
return result
print ''.join(sorted(sys.stdin.readlines(), key=SortKey)),
L.sort(key=lambda s:int(''.join(filter(str.isdigit,s[-4:]))))