python以数字结尾对字符串进行排序
对末尾有数字的字符串列表进行排序的最简单方法是什么?有些字符串有3位,有些字符串有4位:python以数字结尾对字符串进行排序,python,string,sorting,natural-sort,Python,String,Sorting,Natural Sort,对末尾有数字的字符串列表进行排序的最简单方法是什么?有些字符串有3位,有些字符串有4位: >>> 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放在最后。有没有一种简单的方法可以做到这一点?问题是这里的排序是按字母顺序排列的,因为它们是字符串。在移动到下一个字符之前,对每个字符序列进行比较
>>> 'a1234' < 'a124' <----- positionally '3' is less than '4'
True
>>>
有没有一个简单的方法可以做到这一点
没有
真正的规则是什么还不清楚。“有些有3位,有些有4位”并不是一个非常精确或完整的规范。你所有的例子都在数字前显示了4个字母。这总是真的吗
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))
该键
函数可能会执行您想要的操作。或者它可能太复杂了。或者可能模式真的是r“^(.*)(\d{3,4})$”
,或者规则更加模糊
>>> data= ['asdf123', 'asdf1234', 'asdf111', 'asdf124']
>>> data.sort( key=key )
>>> data
['asdf111', 'asdf123', 'asdf124', 'asdf1234']
您需要一个键函数。您愿意在末尾指定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
函数来获取要比较的值,因此现在将对元素进行比较,就像key函数返回的元组一样。例如,'asdfbad123'
将与'asd7890'
进行比较,因为('asdfbad',123)
与('asd',7890)
进行比较。如果字符串的最后3个字符实际上不是数字,您将得到一个ValueError,这是非常合适的,因为您向它传递的数据不符合它的设计规格。您可能描述的是所谓的a或人类排序。如果您使用的是Python,那么可以从中借用
L.sort(key=lambda s:int(''.join(filter(str.isdigit,s[-4:]))))
自然排序的算法大致如下:
- 将每个值拆分为字母“块”和数字“块”
- 按每个值的第一个块排序
- 如果区块是按字母顺序排列的,则按常规进行排序
- 如果区块是数字的,则按表示的数字值排序
- 获取具有相同第一个块的值,并按第二个块对它们进行排序
- 等等
完全公开,我是这个包的作者。我不是自己拆分每一行,而是让python用
re.findall()
为我做这件事:
请不要将
list
用作变量名。这真是个糟糕的主意。aaronasterling给了我这样的想法:L.sort(key=lambda s:int((s[-3:],s[-4:])[s[-4]在'1234567890'中])这不好,因为'asdf23asdf1234'呢?你的指令中的解决方案很好,但很棘手。但是您仍然需要将字符串的其余部分包含在两个解决方案中进行排序。如果您坚持要比较字符串的其余部分,您仍然应该使用数字作为第一个键,其余部分作为第二个键。这将是非常意外的。如果字母在字符串中排在第一位,那么它们在键元组中应该排在第一位。所以“aaron345”应该在“bob123”之前排序。这将是一个很好的解决方案,早在有趣之前(是的,在某一点上很有趣)key
自2.4以来一直存在,而cmp
在3.x中被弃用并删除。我真不知道这样的垃圾怎么会得到两张选票。它甚至不比较其他字符串。它们删除了cmp?认真地我很失望。您现在应该如何以相反的顺序对字符串进行排序——在之后显式地反转?这并不是说你可以用lambda x:-x作为键来否定字符串…@KarlKnechtel看到这条评论已经9年了,你现在可能已经知道了这一点,但是你可以在排序时使用reverse
关键字参数对sort
进行反向排序。这几乎正是我要告诉询问者的。他需要定义一个正则表达式来分离他的混合输入,解析整数部分,并进行相应的排序。这是一个救命稻草!简单高效
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)
L.sort(key=lambda s:int(''.join(filter(str.isdigit,s[-4:]))))
>>> from natsort import natsorted
>>> natsorted(['asdf123', 'asdf1234', 'asdf111', 'asdf124'])
['asdf111', 'asdf123', 'asdf124', 'asdf1234']
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)),