セットが空の場合はブール値を返します


99

関数の最後でセットが空の場合にブール値を返すよりクリーンな方法を見つけるのに苦労しています

2つのセットの共通部分を取得し、結果のセットが空であるかどうTrueかにFalse基づいて戻りたいと思います。

def myfunc(a,b):
    c = a.intersection(b)
    #...return boolean here

私の最初の考えはすることでした

return c is not None

しかし、私の通訳では、次の場合にステートメントがtrueを返すことが簡単にわかります。 c = set([])

>>> c = set([])
>>> c is not None
True

また、次のすべてを試しました。

>>> c == None
False
>>> c == False
False
>>> c is None
False

今私は、私が唯一使用できることをドキュメントから読んでandorそして、notブール値を推定するために、空のセットを持ちます。これまでのところ、私が思いつくことができるのは、cではなく戻ることだけです。

>>> not not c
False
>>> not c
True

私はそれを見つけるのに苦労しているので、これを行うためのはるかに多くのpythonicな方法があると感じています。値は必要ないので、実際のセットをifステートメントに戻したくありません。値が交差するかどうかを知りたいだけです。


4
あなたはそれをキャストした場合、空のセットがブールFalseに同等であると考えられている:bool(set([]))
woozyking

3
ちなみに、真剣によく練られた質問は注目に値します。
ジョナス・シェーファー

@JonasWielickiありがとう!答えに感謝します-それがそれらの線に沿った何かであることを知っていました。
CB

この質問は5年になり、誰もを使用することを提案しませんisdisjointでした。私は完全にショックを受けました。
アディリオ

回答:


71
def myfunc(a,b):
    c = a.intersection(b)
    return bool(c)

bool()に似た何かをしますがnot not、よりイデオマティックで明確です。


9
私は反対します、bool(...)あなたが尋ねているときに書くことis_emptyはあいまいです。私はその意図を表明しません。
tamas.kenez

2
@ tamas.kenezただし、not not;)よりも明確であることを認める必要があります。(FTR:私はすでに@gefeis upvoted答えを持っていたが、私は事のOPに影響を持っていない...受け入れ)
ジョナス・シェーファー

113

他の答えほどパイソンではありませんが、数学:

return len(c) == 0

いくつかのコメントlen(set)が複雑さに与える影響について疑問に思ったように。セットの使用状況を追跡する変数に依存している場合、ソースコードに示されているようにO(1)です。

static Py_ssize_t
set_len(PyObject *so)
{
    return ((PySetObject *)so)->used;
}

10
これは実際には良いと思います。それはあなたの意図が何であるかをより明確にします。
arshajii 2014年

4
非常に大きいlen(c)場合でもc、これを計算する必要があるのではないかと思います。これは、空をチェックするために不要です。
ミケーレデパスカリス

1
@Glaedr一般的に使用されるデータ構造(つまり、リスト、セット)のcpython lenはO(1)であると信じています(つまり、長さを表すデータ構造に変数を格納します)
CB

2
^ +1 @CB len(c)でいくつかのテストを行いましたが、セットサイズが劇的に変化したときに実行時の違いが無視できるため、これは間違いなくlenを表す変数です。
dster77 2017

1
@ dster77両方のバージョンでコードのプロファイルを作成しましたが、set()(Windowsのpython 3.5.2)と比較すると大幅に高速
でした

26

あなたがしたい場合はreturn True、空のセットのために、私はそれを行うには明確だと思います。

return c == set()

つまり、「cは空の」と同じsetです。

(または、その逆の場合は、return c != set())。

私の意見では、これはFalseブール値のコンテキストのように空のセットのPythonの解釈に依存するよりも明確です(慣用的ではありませんが)。


2
実際、Pythonの解釈に依存することは非常に受け入れられる方法です。その制限を念頭に置いている限り。
火山

17

cがセットの場合、次のようにして空かどうかを確認できますreturn not c

c空の場合はにnot cなりますTrue

それ以外の場合、c要素not cが含まれている場合はになりますFalse


7

あなたが言う時:

c is not None

実際には、cとNoneが同じオブジェクトを参照しているかどうかを確認しています。それが「is」演算子が行うことです。Pythonでは、Noneは通常、使用可能な値がないことを意味する特別なnull値です。cまたはjavaのnullのような並べ替え。Pythonは内部的に、「is」演算子を使用して1つのNone値のみを割り当て、何かがNone(nullと考えられる)であるかどうかを確認するため、これが一般的なスタイルになっています。ただし、これは集合cの真理値とは関係ありません。これは、cがnull値ではなく実際に集合であることを確認しています。

条件ステートメントでセットが空であるかどうかを確認する場合は、コンテキストでブール値としてキャストされるため、次のように言うことができます。

c = set()
if c:
   print "it has stuff in it"
else:
   print "it is empty"

ただし、ブール値に変換して保存したい場合は、次のように簡単に言うことができます。

c = set()
c_has_stuff_in_it = bool(c)

1
"""
This function check if set is empty or not.
>>> c = set([])
>>> set_is_empty(c)
True

:param some_set: set to check if he empty or not.
:return True if empty, False otherwise.
"""
def set_is_empty(some_set):
    return some_set == set()

0

bool(c)ほどきれいではありませんが、三項を使用する言い訳でした。

def myfunc(a,b):
    return True if a.intersection(b) else False

また、同じロジックを少し使用すると、他の目的で使用しない限り、cに割り当てる必要はありません。

def myfunc(a,b):
    return bool(a.intersection(b))

最後に、ある種のブールテストを実行するため、True / False値が必要であると想定します。必要な場所をテストするだけで、関数呼び出しと定義のオーバーヘッドをスキップすることをお勧めします。

の代わりに:

if (myfunc(a,b)):
    # Do something

多分これ:

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