python使用to criteria对列表中的对象进行排序

时间:2014-06-12 11:06:51

标签: python sorting

我有一个包含两个属性first_namelast_name的对象列表。我希望能够先按last_name然后按first_name对名称进行排序。

例如,如果排序John JamesAndrew 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)

但是当我有两个对象时,如下所示

  1. Nikos Galis
  2. Nigel Reynolds
  3. 如果我使用上面的代码,它首先显示Nigel(因为Nigel来自Nikos之前),这不是我想要的。我想上面的代码可以在我们在两个对象中都有相同的last_name的情况下工作,但是当对象不同时它并不像我想要的那样工作。有解决方案吗?

1 个答案:

答案 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')]