python基于另一个列表的顺序的属性对对象列表进行排序

时间:2013-03-29 10:52:03

标签: python list sorting

每个人,我需要你对python list sort的帮助。

事情就是这样:

我有两个列表:一个是整数列表,另一个是对象列表,第二个对象列表的属性id也是一个整数,我想根据id属性对对象列表进行排序,在第一个列表中出现相同id的顺序,这是一个例子:

我得到了= [1,2,3,4,5]

和b = [o,p,q,r,s],其中o.id = 2,p.id = 1,q.id = 3,r.id = 5,s.id = 4

我希望我的列表b按照其ID出现在列表a中的顺序进行排序,如下所示: sorted_b = [p,o,q,s,r]

当然,我可以通过使用嵌套循环实现这一点:

sorted_b = []
for i in a:
    for j in b:
        if j.id == i:
            sorted_b.append(j)
            break

但这是解决问题的经典丑陋和非蟒蛇方式,我想知道是否有一种方法可以用一种相当简洁的方式解决这个问题,比如使用排序方法,但我不知道怎么做。 我用Google搜索了我的问题,但找不到确切的答案,所以我需要你的帮助,谢谢:)

4 个答案:

答案 0 :(得分:7)

>>> from collections import namedtuple
>>> Foo = namedtuple('Foo', 'name id') # this represents your class with id attribute
>>> a = [1,2,3,4,5]
>>> b = [Foo(name='o', id=2), Foo(name='p', id=1), Foo(name='q', id=3), Foo(name='r', id=5), Foo(name='s', id=4)]
>>> sorted(b, key=lambda x: a.index(x.id))
[Foo(name='p', id=1), Foo(name='o', id=2), Foo(name='q', id=3), Foo(name='s', id=4), Foo(name='r', id=5)]

答案 1 :(得分:2)

这是一种简单的方法:

# Create a dictionary that maps from an ID to the corresponding object
object_by_id = dict((x.id, x) for x in b)

sorted_b = [object_by_id[i] for i in a]

如果列表变大,它可能也是最快的方式。

答案 2 :(得分:1)

你可以用列表理解来做到这一点,但总的来说它是一样的。

sorted_b = [ y for x in a for y in b if y.id == x ]

答案 3 :(得分:0)

Python中有一个sorted函数。它采用可选的关键字参数cmp。您可以通过自定义函数进行排序。

来自文档的

cmp定义:

  

自定义比较应返回负数,零或正数,具体取决于第一个参数是否小于,等于或大于第二个参数

a = [1,2,3,4,5]
def compare(el1, el2):
   if a.index(el1.id) < a.index(el2.id): return -1
   if a.index(el1.id) > a.index(el2.id): return 1
   return 0

sorted(b, cmp=compare)

这更直接但是我鼓励你使用key参数作为他的回答中描述的jamylak,因为它更加pythonic,而在Python 3中cmp不再受支持。