Küme boşsa boole döndürülüyor


97

Fonksiyonumun sonunda setim boşsa, bir boole değerini döndürmenin daha temiz bir yolunu bulmakta zorlanıyorum

Ben iki set kesişimi almak ve dönmek istiyorum Trueya Falseçıkan kümesi boşsa dayalı.

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

İlk düşüncem yapmaktı

return c is not None

Ancak, tercümanımda bu ifadenin doğru döneceğini kolayca görebiliyorum. c = set([])

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

Ayrıca aşağıdakilerin tümünü denedim:

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

Şimdi ben sadece kullanabileceği belgelerinden okudum and, orve, notbir boolean değerini anlamak için boş setleri ile. Şimdiye kadar bulabildiğim tek şey geri dönmek değil c

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

Bunu yapmanın çok daha pitonik bir yolu olduğunu hissediyorum, onu bulmak için çabalıyorum. Gerçek kümeyi bir if ifadesine döndürmek istemiyorum çünkü değerlere ihtiyacım yok, sadece kesişip kesişmediklerini bilmek istiyorum.


4
Eğer öyle dökme eğer boş seti boole Yanlış eşdeğer olarak kabul edilir:bool(set([]))
woozyking

3
bu arada, dikkate değer olan ciddi şekilde iyi işlenmiş bir soru.
Jonas Schäfer

@JonasWielicki Teşekkürler! Cevabı takdir edin - bu doğrultuda bir şey olduğunu biliyordum.
CB

Bu soru 5 yıl sürecek ve kimse kullanmayı önermedi isdisjoint. Ben tamamen şok oldum.
Adirio

Yanıtlar:


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

bool()benzer bir şey yapacak not not, ama daha ideomatik ve net.


7
İtiraz bool(...)ediyorum, sorduğun zaman yazmak is_emptymuğlaktır. Niyeti ifade etmiyorum.
tamas.kenez

2
@ tamas.kenez Yine de not not;) ' den daha açık olduğunu kabul etmelisiniz . (FTR: @gefeis cevabını zaten yükseltmiştim, ancak OP'nin kabul ettiği şey üzerinde etkim yok…)
Jonas Schäfer

109

diğer cevaplar kadar pitonik değil, matematik:

return len(c) == 0

Bazı yorumların len(set)karmaşıklık üzerindeki etkisi hakkında merak ettiği gibi. Kümenin kullanımını izleyen bir değişkene bağlı olduğu için kaynak kodda gösterildiği gibi O (1) 'dir .

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

9
Bunun aslında daha iyi olduğunu düşünüyorum. Niyetinizin ne olduğunu daha net hale getirir.
arshajii

4
Korkarım ki bu çok büyük len(c)olsa bile hesaplamak zorunda kalacak c, ki bu boşluğu kontrol etmek için gereksiz.
Michele De Pascalis

1
@Glaedr Yaygın olarak kullanılan veri yapıları (yani liste, küme) için cpython len'in O (1) olduğuna inanıyorum (yani uzunluğu temsil eden veri yapısında bir değişken depoluyorlar)
CB

2
^ +1 @CB len (c) üzerinde bazı testler yaptım ve kesinlikle len'i temsil eden bazı değişkenlerdi çünkü set boyutu dramatik büyüklük sıralarını değiştirdiğinde ihmal edilebilir çalışma zamanı farkı vardı.
dster77

1
@ dster77 Kodumun profilini her iki sürümle de oluşturdum ve set()(windows'da python 3.5.2) ile karşılaştırıldığında önemli ölçüde daha hızlıydı
mathiasfk

23

Eğer istersen return Trueboş bir set için, o zaman ben bunu yapmak daha net olacağını düşünüyorum:

return c == set()

yani " cboşa eşittir set".

(Ya da tam tersi için return c != set()).

Bana göre bu, Python'un Falseboole bağlamında olduğu gibi boş bir küme yorumuna güvenmekten daha açık (ama daha az deyimsel) .


2
Aslında, Python'un yorumuna güvenmek çok kabul edilebilir bir uygulamadır. Sınırlamaları akılda tutulduğu sürece.
yanardağ

17

Eğer ckümesidir o zaman yaparak boş olup olmadığını kontrol edebilirsiniz: return not c.

Eğer cboş sonra not colacak True.

Aksi takdirde cherhangi bir öğe içeriyorsa not colacaktır False.


6

Dediğinde:

c is not None

Aslında c ve Hiçbirinin aynı nesneye başvurup başvurmadığını kontrol ediyorsunuz. "Olan" operatörünün yaptığı budur. Python'da Yok özel bir boş değerdir, yani mevcut bir değeriniz yoktur. C veya java'da null gibi sorta. Python dahili olarak bir şeyin Yok olup olmadığını kontrol etmek için "is" operatörünü kullanarak yalnızca bir None değeri atadığından (boş düşünün) ve bu popüler stil haline geldi. Ancak bunun c kümesinin doğruluk değeri ile bir ilgisi yoktur, c'nin aslında bir boş değerden ziyade bir küme olduğunu kontrol eder.

Koşullu bir ifadede bir kümenin boş olup olmadığını kontrol etmek isterseniz, bağlamda bir boole olarak çevrilir, böylece şunu söyleyebilirsiniz:

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

Ancak, depolanmak üzere bir boole'ye dönüştürülmesini istiyorsanız, şunu söyleyebilirsiniz:

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) kadar temiz değil ama üçlü kullanmak için bir bahaneydi.

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

Ayrıca aynı mantığın bir kısmını kullanarak, başka bir şey için kullanmadığınız sürece c'yi atamanıza gerek yoktur.

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

Son olarak, bir Doğru / Yanlış değeri istediğinizi varsayıyorum çünkü onunla bir çeşit boole testi yapacaksınız. Basitçe ihtiyacınız olan yerde test ederek bir işlev çağrısı ve tanımının ek yükünü atlamanızı öneririm.

Onun yerine:

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

Belki bu:

if a.intersection(b):
    # Do something
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.