複数のリストに含まれるすべての値の和集合を作成するPythonの方法


84

私はリストのリストを持っています:

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

このリストをフラットにして、すべての重複を削除したいと思います。または、言い換えると、集合和集合演算を適用します。

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

これを行う最も簡単な方法は何ですか?

回答:


152

set.union あなたが望むことをします:

>>> results_list = [[1,2,3], [1,2,4]]
>>> results_union = set().union(*results_list)
>>> print(results_union)
set([1, 2, 3, 4])

3つ以上のリストでこれを行うこともできます。


@sth、たとえば感謝しますが、実行するとエラーが発生します:トレースバック(最後の最後の呼び出し):ファイル "so_example.py"、33行目?。results_union =セット()組合(* result_lists)はTypeError:組合()正確に一つの引数(3、与えられた)かかり
AJを。

1
@AJ:ドキュメント(docs.python.org/library/stdtypes.html#set.union)によると、union()Pythonバージョン2.6以降では複数の引数のみがサポートされています。その前のバージョンを使用しているように見えるので、おそらく明示的なループを使用する必要があります:total = set(); for x in results_list: total.update(x) (s /; / \ n /)
sth 2010年

2
2行目をresults_union = set.union(*(set(el) for el in results_list))
Noel Evans

1
@ TypeError: descriptor 'union' requires a 'set' object but received a 'list'Jean-少なくともPython3.6のFrançoisFabre 。
パリトッシュシン

1
使用するset.union(*results_list)場合は、メソッド記述子を手動でバインドします。つまり、の最初の要素をresults_list「self」として送信します。これにより、いくつかの奇妙な制限が発生します。1。ダックタイピングが適切に行われない(最初の要素はセットまたはセットサブクラスのインスタンスである必要があります)、2。空の和集合はresults_listエラーになります(誤った結果-空を返す必要があります)セットする)。
WIM

12

Python 2.5を使用しているように見えるので(バージョン!= 2.6のAが必要な場合は、Qで言及するとよいでしょう。ちなみに、現在の製品版です;-)、セットではなくリストが必要です。結果、私はお勧めします:

import itertools

...

return list(set(itertools.chain(*result_list)))

itertoolsは、一般的にイテレーター(および多くの種類のシーケンスまたはコレクション)を操作するための優れた方法であり、慣れることを心からお勧めします。 itertools.chain特に、ここに記載されています


+1素晴らしいitertoolsパッケージに浸る良い時間の完璧な例。
gotgenes 2010年

@Alexありがとう...バージョンを指定し、バージョンが遅れていることに対する自分のせいを取り除くために私の質問を編集しました:) itertoolsを調べて、提案に感謝します。
AJ。

@AJ、責任はありません。結局のところ、私たち全員がそのような制約の下で苦しむ可能性があります(ただし、将来のQで指定することを忘れないでください!-); itertools.chainちなみに、Python2.4でも問題なく動作します。
Alex Martelli 2010年

3

このスタイルに従うこともできます

In [12]: a = ['Orange and Banana', 'Orange Banana']
In [13]: b = ['Grapes', 'Orange Banana']
In [14]: c = ['Foobanana', 'Orange and Banana']

In [20]: list(set(a) | set(b) | set(c))
Out[20]: ['Orange and Banana', 'Foobanana', 'Orange Banana', 'Grapes']

In [21]: list(set(a) & set(b) | set(c))
Out[21]: ['Orange and Banana', 'Foobanana', 'Orange Banana']    


0

私は以下を使用して交差を行いました。これにより、セットが不要になります。

a, b= [[1,2,3], [1,2]]
s = filter( lambda x: x in b, a)

または、

s = [ x for x in b if x in a ]

5
なぜ「セットの必要性を避けたい」のでしょうか?この目的のために、それらはより速く、より明確です。また、「x in a」は、実行するたびにリストをブルートフォースで線形検索します。うん。
Peter Hansen

セットは、型キャストを必要とし、あなたは大きなN.を扱っている場合を除き、線形速度は悪くないです
ベア

3
「型キャスト」?Pythonでは?いつから?セットは基本的にキーのみのdictであり、ハッシュと等価性の比較を使用します。リストで「xina」を使用すると、等価比較も行われます。型キャストについてこれは何ですか?
Peter Hansen

0

理解の方法で:

[*{ j for i in lists for j in i }]

または

[*functools.reduce(lambda x,y: {*x, *y}, lists)]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.