ส่งคืนบูลีนหากชุดว่าง


97

ฉันกำลังดิ้นรนเพื่อหาวิธีคืนค่าบูลีนที่สะอาดยิ่งขึ้นหากชุดของฉันว่างเปล่าเมื่อสิ้นสุดฟังก์ชัน

ฉันใช้จุดตัดของสองชุดและต้องการส่งคืนTrueหรือFalseขึ้นอยู่กับว่าชุดผลลัพธ์ว่างเปล่า

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

ความคิดแรกของฉันคือการทำ

return c is not None

อย่างไรก็ตามในล่ามของฉันฉันสามารถเห็นได้อย่างง่ายดายว่าคำสั่งนั้นจะกลับมาเป็นจริงถ้า c = set([])

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

ฉันได้ลองทำสิ่งต่อไปนี้ทั้งหมดแล้ว:

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

ตอนนี้ผมได้อ่านจากเอกสารที่ฉันสามารถใช้and, orและnotกับเซตว่างที่จะอนุมานค่าบูลีน จนถึงตอนนี้สิ่งเดียวที่ฉันคิดได้คือการกลับมาไม่ใช่ c

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

ฉันรู้สึกว่ามีวิธีที่ยิ่งใหญ่กว่านี้อีกมากที่จะทำเช่นนี้โดยฉันพยายามดิ้นรนเพื่อหามัน ฉันไม่ต้องการคืนค่าชุดจริงให้เป็นคำสั่ง if เพราะฉันไม่ต้องการค่าฉันแค่อยากรู้ว่ามันตัดกันหรือไม่


4
เซตว่างจะถือว่าเป็นบูลีนเท็จเทียบเท่าหากคุณร่าย:bool(set([]))
woozyking

3
อย่างไรก็ตามคำถามที่ได้ผลดีอย่างจริงจังซึ่งน่าทึ่งมาก
Jonas Schäfer

@JonasWielicki ขอบคุณ! ชื่นชมคำตอบ - รู้ว่ามันเป็นอะไรบางอย่างตามแนวเหล่านั้น
CB

คำถามนี้จะเปิด 5 isdisjointปีและไม่มีใครแนะนำให้ใช้ ฉันตกใจมาก
Adirio

คำตอบ:


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

bool()จะทำสิ่งที่คล้ายกันnot notแต่มีอุดมการณ์และชัดเจนมากขึ้น


7
ฉันคัดค้านการเขียนbool(...)เมื่อคุณขอis_emptyนั้นคลุมเครือ ฉันไม่ได้แสดงเจตนา
tamas.kenez

2
@ tamas.kenez คุณต้องยอมรับว่ามันชัดเจนกว่าnot not;) (FTR: ฉันได้โหวตคำตอบของ @gefeis ไปแล้ว แต่ฉันไม่มีอิทธิพลต่อสิ่งที่ OP ยอมรับ…)
Jonas Schäfer

109

ไม่ใช่ pythonic เหมือนคำตอบอื่น ๆ แต่เป็นคณิตศาสตร์:

return len(c) == 0

เนื่องจากบางความคิดเห็นสงสัยเกี่ยวกับผลกระทบที่len(set)อาจมีต่อความซับซ้อน มันคือ O (1) ตามที่แสดงในซอร์สโค้ดที่ระบุโดยอาศัยตัวแปรที่ติดตามการใช้งานของชุด

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

9
ฉันคิดว่าสิ่งนี้ดีขึ้นจริง ทำให้ชัดเจนขึ้นว่าเจตนาของคุณคืออะไร
arshajii

4
ฉันเกรงว่าจะต้องคำนวณlen(c)แม้ว่าcจะมีขนาดใหญ่มากก็ตามซึ่งไม่จำเป็นเพื่อตรวจสอบความว่างเปล่า
Michele De Pascalis

1
@Glaedr ฉันเชื่อใน cpython len สำหรับโครงสร้างข้อมูลที่ใช้กันทั่วไป (เช่น list, set) คือ O (1) (เช่นพวกเขาเก็บตัวแปรไว้บนโครงสร้างข้อมูลแทนความยาว)
CB

2
^ +1 @CB ฉันได้ทำการทดสอบเกี่ยวกับ len (c) และแน่นอนว่ามันเป็นตัวแปรบางตัวที่แสดงถึง len เนื่องจากมีความแตกต่างของรันไทม์เล็กน้อยเมื่อขนาดที่ตั้งไว้เปลี่ยนลำดับความสำคัญอย่างมาก
dster77

1
@ dster77 ฉันทำโปรไฟล์โค้ดของฉันด้วยทั้งสองเวอร์ชันและเร็วกว่าอย่างมากเมื่อเปรียบเทียบกับset()(python 3.5.2 ใน windows)
mathiasfk

23

หากคุณต้องการreturn Trueเซตว่างฉันคิดว่ามันจะชัดเจนกว่าที่จะทำ:

return c == set()

คือ " cเท่ากับว่างset"

(หรือในทางกลับกันreturn c != set())

ในความคิดของฉันนี่เป็นเรื่องที่ชัดเจนกว่า (แม้ว่าจะเป็นสำนวนน้อยกว่า) มากกว่าการใช้การตีความของ Python เกี่ยวกับชุดว่างFalseในบริบทบูลีน


2
ที่จริงแล้วการอาศัยการตีความของ Python เป็นวิธีปฏิบัติที่ยอมรับได้ ตราบเท่าที่ข้อ จำกัด ยังคงอยู่ในใจ
ภูเขาไฟ

17

ถ้าเป็นชุดแล้วคุณสามารถตรวจสอบว่ามันว่างเปล่าโดยการทำ:creturn not c

ถ้าcเป็นที่ว่างเปล่าแล้วจะnot cTrue

มิฉะนั้นถ้าcมีองค์ประกอบใด ๆ ที่จะเป็นnot cFalse


6

เมื่อคุณพูดว่า:

c is not None

คุณกำลังตรวจสอบว่า c และไม่มีอ้างอิงวัตถุเดียวกันหรือไม่ นั่นคือสิ่งที่ตัวดำเนินการ "is" ทำ ใน python ไม่มีเป็นค่าว่างพิเศษตามอัตภาพหมายความว่าคุณไม่มีค่าที่พร้อมใช้งาน จัดเรียงเช่น null ใน c หรือ java เนื่องจาก python ภายในกำหนดค่า None เพียงค่าเดียวโดยใช้โอเปอเรเตอร์ "is" เพื่อตรวจสอบว่าสิ่งที่ None (คิดว่าเป็นโมฆะ) ทำงานได้หรือไม่และได้กลายเป็นรูปแบบยอดนิยม อย่างไรก็ตามสิ่งนี้ไม่เกี่ยวข้องกับค่าความจริงของเซต c แต่กำลังตรวจสอบว่า c เป็นเซตแทนที่จะเป็นค่าว่าง

หากคุณต้องการตรวจสอบว่าชุดนั้นว่างเปล่าในคำสั่งเงื่อนไขชุดนั้นจะถูกส่งเป็นบูลีนในบริบทเพื่อให้คุณสามารถพูดได้ว่า:

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

ไม่สะอาดเท่าบูล (c) แต่มันเป็นข้ออ้างในการใช้ ternary

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.