我有一个相同类型的对象列表
lis = [<obj>, <obj>, <obj>]
Run Code Online (Sandbox Code Playgroud)
我希望通过object属性自然排序name.我试过了
sortedlist = sorted(lis, key=lambda x: x.name)
Run Code Online (Sandbox Code Playgroud)
然而,这将列表排序为
A1
A10
A2
Run Code Online (Sandbox Code Playgroud)
不是我想要的格式
A1
A2
A10
Run Code Online (Sandbox Code Playgroud)
我已经尝试修改代码来排序字母数字字符串,但我不能让它适用于对象列表.
这种方式使用groupby,适用于alpha和数字之间的任意数量的交换
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)
Run Code Online (Sandbox Code Playgroud)
演示:
>>> my_list =['A1', 'A10', 'A2', 'B0', 'AA11', 'AB10']
>>> sorted(my_list, key=keyfunc)
['A1', 'A2', 'A10', 'AA11', 'AB10', 'B0']
>>> mylist =['foo1', 'foo10', 'foo2', 'foo2bar1', 'foo2bar10', 'foo2bar3']
>>> sorted(mylist, key=keyfunc)
['foo1', 'foo2', 'foo2bar1', 'foo2bar3', 'foo2bar10', 'foo10']
Run Code Online (Sandbox Code Playgroud)
sorted(obj, key=lambda x: (x.name[0], int(x.name[1:])))
Run Code Online (Sandbox Code Playgroud)
像这样的东西:
import re
def func(x):
foo = re.search(r'([A-Z]+)(\d+)',x.name)
return foo.group(1), int(foo.group(2))
print sorted(obj, key = func)
Run Code Online (Sandbox Code Playgroud)
演示:
lis =['A1', 'A10', 'A2', 'B0', 'AA11', 'AB10']
def func(x):
foo = re.search(r'([A-Z]+)(\d+)',x)
return foo.group(1), int(foo.group(2))
print sorted(lis, key = func)
#['A1', 'A2', 'A10', 'AA11', 'AB10', 'B0']
Run Code Online (Sandbox Code Playgroud)
稍微修改过的版本sorted_nicely可以适用于您的对象:
def sorted_nicely( x ):
""" Sort the given iterable in the way that humans expect."""
convert = lambda text: int(text) if text.isdigit() else text
return [ convert(c) for c in re.split('([0-9]+)', x.name) ]
obj.sort(key = sorted_nicely)
#or sorted(obj, key = sorted_nicely)
Run Code Online (Sandbox Code Playgroud)