3

私はPythonリストソートを使用しています。

2 つのリストがあります。1 つは整数のリスト、もう 1 つはオブジェクトのリストです。2 番目のオブジェクト リストには、同じく整数である属性 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 を、リスト a に表示される ID の順に並べ替えます。これは次のようになります。

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

You can do it with a list comprehension, but in general is it the same.

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

Python にはsorted関数があります。オプションのキーワード引数を取りますcmp。ソート用にカスタマイズした関数をそこに渡すことができます。

cmpドキュメントからの定義:

カスタム比較は、最初の引数が 2 番目の引数より小さい、等しい、または大きいと見なされるかどうかに応じて、負、ゼロ、または正の数値を返す必要があります。

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 に答える