今朝スクリプトを書いているときに、予期していなかったことに気づきました。リスト内包表記を使用して、すべてを1つのステートメントに並べ替えようとすると、驚くべき結果が得られました。次のコードは私の一般的な使用例を要約していますが、この質問のために簡略化されています。
Transaction = namedtuple('Transaction', ['code', 'type'])
my_list = [Transaction('code1', 'AAAAA'), Transaction('code2', 'BBBBB'), Transaction('code3', 'AAAAA')]
types = ['AAAAA', 'CCCCC']
result = [trans for trans in my_list if trans.type in types].sort(key = lambda x: x.code)
print result
出力:
None
内包表記を使用してリストを作成し、事後に並べ替えると、すべて問題ありません。なぜこれが起こるのか興味がありますか?
メソッドlist.sort()
はリストを適切にソートしており、すべての変更メソッドと同様にNone
を返します。組み込み関数 sorted()
を使用して、新しいソート済みリストを返します。
_result = sorted((trans for trans in my_list if trans.type in types),
key=lambda x: x.code)
_
_lambda x: x.code
_の代わりに、少し高速なoperator.attrgetter("code")
を使用することもできます。
リストで_.sort
_を呼び出すと、None
が返されます。この結果がresult
に割り当てられることは完全に理にかなっています。
つまり、リスト内包表記を使用して匿名でリストを作成し、_.sort
_を呼び出すと、_.sort
_呼び出しの結果がresult
変数に格納されている間、リストは失われます。
他の人が言っているように、リストを返すにはsorted()
組み込み関数を使用する必要があります。 (sorted()
は、リストのソートされたコピーを返します。)
sorted
組み込み関数が必要です。 sort
メソッドは、リストをその場でソートし、None
を返します。
result = sorted([trans for trans in my_list if trans.type in types],key = lambda x: x.code)
これは、次の方法で少し改善できます。
import operator
result = sorted( (trans for trans in my_list if trans.type in types ), key=operator.attrgetter("code"))