2

最初と 3 番目の項目が同じで、最初の項目だけを保持しているリストからリストを削除しようとしています。リストと出力の例:

li=[ [2,4,5], [1,3,5], [1,6,5] ]
output_list = [ [2,4,5], [1,3,5] ]

元のリストには数百万のリストが含まれているため、私が書いたコードの実行には非常に長い時間がかかります。

b_li = []
output_list = []
for x in li:
    s = [ x[0], x[2] ]
    if s not in b_li:
        b_li.append(s)
        output_list.append(x)

コードを改善するにはどうすればよいですか? 前もって感謝します。

4

4 に答える 4

2

表示された要素を格納するためにセットを使用します。それはより速いです:

seen = set()
res = []
for entry in li:
    cond = (entry[0], entry[2])
    if cond not in seen:
        res.append(entry)
        seen.add(cond)


[[2, 4, 5], [1, 3, 5]]

添加

また、変数名を伝えることについて考えるのに費やす時間は、通常、十分に費やされます。多くの場合、使い捨ての解決策として最初に考えたことが、予想よりもはるかに長く続きます。

于 2013-06-01T23:03:49.950 に答える
2

改良版:

b_li = set()
output_list = []
b_li_add = b_li.add
output_list_append = output_list.append
for x in li:
    s = (x[0], x[2])
    if s not in b_li:
        b_li_add(s)
        output_list_append(x)

変更点は次のとおりです。

  • 検索を高速化するset()forを使用します。b_li
  • 一意sの 1 番目と 3 番目の要素をリストとして格納する必要がないため、タプルに変換します。
  • 関数のルックアップを減らし、コードも高速化します。
于 2013-06-01T23:04:11.077 に答える
1

活用OrderedDictと、辞書には一意のキーがあるという事実。

>>> from collections import OrderedDict
>>> li=[ [2,4,5], [1,3,5], [1,6,5] ]
>>> OrderedDict(((x[0], x[2]), x) for x in reversed(li)).values()
[[1, 3, 5], [2, 4, 5]]
于 2013-06-02T01:15:34.310 に答える
0

これは、@iurisilvio のイテレータ コメントに基づくソリューションであり、他のソリューションからのベースのソリューションitertools.compressと組み合わせて使用​​します。入力リストの要素からset作成する代わりに、ブール値を含むリストが、入力リストの要素に関して 1 対 1 で作成されます。の値は、入力リストの対応する要素を出力に保持する必要があることを示します。次に、入力リストに適用して、出力 iterable を生成できます。output_listselectorTrueselectoritertools.compress

from itertools import compress
li=[ [2,4,5], [1,3,5], [1,6,5] ]
b_li = set()
selectors = []
for x in li:
    s = (x[0], x[2])
    if s not in b_li:
        b_li.add(s)
        selectors.append(True)
    else:
        selectors.append(False)

for x in compress(li, selectors):
  print x
[2, 4, 5]
[1, 3, 5]
于 2013-06-01T23:22:34.213 に答える