3

我正在使用 Python 列表排序。

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

我有a = [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

但这是一种经典的丑陋且非 Python 解决问题的方法,我想知道是否有一种方法可以以一种相当简洁的方式解决这个问题,比如使用 sort 方法,但我不知道如何。

4

4 回答 4

8
>>> 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)]
于 2013-03-29T10:56:46.123 回答
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]

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

于 2013-03-29T11:27:18.683 回答
1

您可以使用列表推导来做到这一点,但总的来说是一样的。

sorted_b = [ y for x in a for y in b if y.id == x ]
于 2013-03-29T10:59:59.817 回答
0

Python中有一个排序函数。它需要可选的关键字参数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不再支持。

于 2013-03-29T11:10:02.333 回答