web-dev-qa-db-ja.com

Python Unionの設定とIntersectionの設定の動作は異なりますか?

私はPythonでいくつかの集合演算を行っていますが、奇妙なことに気づきました。

>> set([1,2,3]) | set([2,3,4])
set([1, 2, 3, 4])
>> set().union(*[[1,2,3], [2,3,4]])
set([1, 2, 3, 4])

それは良い、期待される振る舞いです-しかし、交点がある場合:

>> set([1,2,3]) & set([2,3,4])
set([2, 3])
>> set().intersection(*[[1,2,3], [2,3,4]])
set([])

ここで気を失いましたか? set.intersection()が期待どおりに動作しないのはなぜですか?

ユニオンで行ったように、多くのセットの共通部分を行うにはどうすればよいですか([[1,2,3], [2,3,4]]にはさらに多くのリストがあったと仮定します)? 「Pythonic」の方法はどうなりますか?

47
Bilal Akil

set()を実行すると、空のセットが作成されます。 set().intersection(...)を実行すると、この空のセットが他のものと交差します。空のセットと他のセットのコレクションとの共通部分は空です。

setsのリストが実際にある場合は、その方法と同様の交差点を取得できます。

>>> x = [{1, 2, 3}, {2, 3, 4}, {3, 4, 5}]
>>> set.intersection(*x)
set([3])

ただし、intersection(*...)の例では実際にはセットがまったくないため、これを行う方法で直接行うことはできません。 listsのリストがあります。まず、リスト内の要素をセットに変換する必要があります。あなたが持っているなら

x = [[1,2,3], [2,3,4]]

やったほうがいい

x = [set(a) for a in x]
79
BrenBarn
set().intersection(*[[1,2,3], [2,3,4]])

空のセットで開始し、他のすべてのセットと交差するため、もちろん空です

classでメソッドを呼び出すことができます

set.intersection(*[[1,2,3], [2,3,4]])

しかし、渡される最初の引数はセットである必要があるため、それは機能しません

set.intersection({1, 2, 3}, *[[2,3,4], ...])

そもそもセットのリストを使用できれば、これは厄介に見えます。特に、それらが発電機から来ている場合、最初のアイテムをきれいに引き離すのが難しくなります

set.intersection(*[{1,2,3}, {2,3,4}])

それ以外の場合は、単にmakeそれらをすべてセットにできます

set.intersection(*(set(x) for x in [[1,2,3], [2,3,4]]))
13
John La Rooy

リストを変換して最初に設定する

>>> set.intersection(*[set([1,2,3]), set([2,3,4])])
set([2, 3])

複数のリストを使用するだけで、

>>> set.intersection(*[set([1,2,3]), set([2,3,4]), set([5,3,4])])
set([3])
10
Anto

[間違った答えを削除]

@Anto Vinishが提案したように、まずリストをセットに変換してからset.intersectionを使用する必要があります

例えば:

>>> sets = [set([1, 2, 3]), set([2, 3, 4]), set([3, 4, 5])]
>>> set.intersection(*sets)
set([3])
1
Hypuk