343

セットのリストがあります:

setlist = [s1,s2,s3...]

s1 ∩ s2 ∩ s3 が欲しい ...

s1.intersection(s2)一連のペアワイズなどを実行することで、それを行う関数を書くことができます。

推奨される、より良い、または組み込みの方法はありますか?

4

7 に答える 7

554

set.intersection()Pythonバージョン2.6以降では、次のように複数の引数を使用できます。

u = set.intersection(s1, s2, s3)

セットがリストにある場合、これは次のように変換されます。

u = set.intersection(*setlist)

リストの展開*a_listはどこですか

set.intersectionこれは静的な方法ではありませんが、機能表記を使用して、最初のセットとリストの残りの部分との共通部分を適用することに注意してください。したがって、引数リストが空の場合、これは失敗します。

于 2010-03-29T22:55:34.360 に答える
86

2.6以降、set.intersection任意に多くの反復可能オブジェクトを取ります。

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s3 = set([2, 4, 6])
>>> s1 & s2 & s3
set([2])
>>> s1.intersection(s2, s3)
set([2])
>>> sets = [s1, s2, s3]
>>> set.intersection(*sets)
set([2])
于 2010-03-29T22:58:49.693 に答える
27

ここで必要なのは明らかset.intersectionですが、「これらすべての合計を取る」、「これらすべての積を取る」、「これらすべての xor をとる」の一般化が必要な場合に備えて、探しているのはreduce関数:

from operator import and_
from functools import reduce
print(reduce(and_, [{1,2,3},{2,3,4},{3,4,5}])) # = {3}

また

print(reduce((lambda x,y: x&y), [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
于 2012-02-29T01:18:36.020 に答える
12

Python 2.6以降を使用していない場合は、明示的なforループを作成することもできます。

def set_list_intersection(set_list):
  if not set_list:
    return set()
  result = set_list[0]
  for s in set_list[1:]:
    result &= s
  return result

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])

また、使用することができますreduce

set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])

ただし、 Guido自身を含め、多くのPythonプログラマーはそれを嫌っています。

約12年前、Pythonはlambda、reduce()、filter()、map()を取得しました。これは、それらを見逃して動作するパッチを提出したLispハッカーの好意によるものです。しかし、PRの価値にもかかわらず、これらの機能はPython3000から削除する必要があると思います。

だから今reduce()。+または*を含むいくつかの例を除いて、重要な関数の引数を使用したreduce()呼び出しを見るたびに、ペンと紙を取得する必要があるため、これは実際に私が常に最も嫌っていたものです。 reduce()が何をするのかを理解する前に、その関数に実際に何が供給されているのかを図解してください。したがって、私の考えでは、reduce()の適用範囲は結合演算子にかなり限定されており、他のすべての場合は、累積ループを明示的に書き出す方がよいでしょう。

于 2010-03-29T22:53:30.713 に答える
1

ここでは、利用可能な最良の方法を利用しようとする複数の集合の共通関数を提供しています。

def multiple_set_intersection(*sets):
    """Return multiple set intersection."""
    try:
        return set.intersection(*sets)
    except TypeError: # this is Python < 2.6 or no arguments
        pass

    try: a_set= sets[0]
    except IndexError: # no arguments
        return set() # return empty set

    return reduce(a_set.intersection, sets[1:])

Guido は嫌いかもしれませんがreduce、私は好きです :)

于 2010-03-31T22:50:38.383 に答える