[英]Sort list of objects by attribute alphanumerically
我有一个相同类型的对象列表
lis = [<obj>, <obj>, <obj>]
我希望通过对象属性name
自然排序。 我努力了
sortedlist = sorted(lis, key=lambda x: x.name)
然而,这将列表排序为
A1
A10
A2
不是我想要的格式
A1
A2
A10
我已经尝试修改代码来排序字母数字字符串 ,但我不能让它适用于对象列表。
这种方式使用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)
演示:
>>> 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']
sorted(obj, key=lambda x: (x.name[0], int(x.name[1:])))
像这样的东西:
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)
演示:
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']
可以为您的对象工作的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)
这回答了OP问题如何通过属性“自然地”对对象列表进行排序:
import re
def natkey(s):
return [w or int(n) for w, n in re.findall('(\D+)|(\d+)', s)]
class X:
def __init__(self, name):
self.name = name
lst = [X('AB1'), X('AB10'), X('AB2'), X('AB12')]
lst.sort(key=lambda obj: natkey(obj.name))
print [obj.name for obj in lst]
# ['AB1', 'AB2', 'AB10', 'AB12']
我能够找到一个基于beauburriers 解决方案的解决方案来进行自然分类
修改为删除自定义键选项
import re
def natural_sort(lis):
"""
Sort the list into natural alphanumeric order.
"""
def get_alphanum_key_func(key):
convert = lambda text: int(text) if text.isdigit() else text
return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))]
sort_key = get_alphanum_key_func(lambda x: x.name)
lis.sort(key=sort_key)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.