我有一个包含两个属性first_name
和last_name
的对象列表。我希望能够先按last_name
然后按first_name
对名称进行排序。
例如,如果排序John James
和Andrew James
,我首先要安德鲁,要约翰。我关注了this并使用了sort
函数
try:
import operator
except:
cmpkey = lambda x: x.last_name
cmpkey2 = lambda x: x.first_name
else:
cmpkey = operator.attrgetter('last_name')
cmpkey2 = operator.attrgetter('first_name')
search_result.sort(key=cmpkey, reverse=False)
search_result.sort(key=cmpkey2, reverse=False)
但是当我有两个对象时,如下所示
如果我使用上面的代码,它首先显示Nigel(因为Nigel来自Nikos之前),这不是我想要的。我想上面的代码可以在我们在两个对象中都有相同的last_name的情况下工作,但是当对象不同时它并不像我想要的那样工作。有解决方案吗?
答案 0 :(得分:3)
您只需排序一次并返回元组:
search_result.sort(key=lambda x: (x.last_name, x.first_name))
元组按字典顺序排列;如果第一个元素相等,则顺序由第二个元素确定。
您可以将lambda
替换为operator.attrgetter()
,并为其提供多个属性来构建元组:
from operator import attrgetter
search_result.sort(key=attrgetter('last_name', 'first_name'))
演示:
>>> from collections import namedtuple
>>> Person = namedtuple('Person', 'first_name last_name')
>>> search_result = [Person('John', 'James'), Person('Andrew', 'James'), Person('Nigel', 'Reynolds'), Person('Nikos', 'Galis')]
>>> search_result.sort(key=lambda x: (x.last_name, x.first_name))
>>> from pprint import pprint
>>> pprint(search_result)
[Person(first_name='Nikos', last_name='Galis'),
Person(first_name='Andrew', last_name='James'),
Person(first_name='John', last_name='James'),
Person(first_name='Nigel', last_name='Reynolds')]
>>> import random
>>> from operator import attrgetter
>>> random.shuffle(search_result)
>>> search_result.sort(key=attrgetter('last_name', 'first_name'))
>>> pprint(search_result)
[Person(first_name='Nikos', last_name='Galis'),
Person(first_name='Andrew', last_name='James'),
Person(first_name='John', last_name='James'),
Person(first_name='Nigel', last_name='Reynolds')]