按字母数字的属性对对象列表进行排序

Sca*_*ger 2 python sorting

我有一个相同类型的对象列表

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)

我已经尝试修改代码来排序字母数字字符串,但我不能让它适用于对象列表.

Joh*_*ooy 6

这种方式使用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)


jam*_*lak 5

sorted(obj, key=lambda x: (x.name[0], int(x.name[1:])))
Run Code Online (Sandbox Code Playgroud)

  • 这适用于这个非常有限的单个字母后跟一些数字的情况:p (2认同)

Ash*_*ary 5

像这样的东西:

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)