ฉันจะตรวจสอบว่ารายการว่างเปล่าได้อย่างไร


3234

ตัวอย่างเช่นหากผ่านสิ่งต่อไปนี้:

a = []

ฉันจะตรวจสอบเพื่อดูว่าaว่างเปล่าได้อย่างไร

คำตอบ:


5493
if not a:
  print("List is empty")

การใช้booleanness โดยนัยของความว่างเปล่าlistนั้นค่อนข้างไพเราะ


1129
เล่นงานผู้สนับสนุนของปีศาจ ฉันไม่เข้าใจว่าทำไมสำนวนนี้จึงถือเป็นไพ ธ อน 'ชัดเจนดีกว่าโดยปริยาย' ถูกต้องไหม ตรวจสอบนี้ดูเหมือนจะไม่ชัดเจนมากเกี่ยวกับสิ่งที่กำลังตรวจสอบ
James McMahon

222
@JamesMcMahon - เป็นการแลกเปลี่ยนระหว่าง explicitness กับความยืดหยุ่นของประเภท โดยทั่วไปการ "ชัดเจน" หมายถึงไม่ทำสิ่งที่ "วิเศษ" ในทางตรงกันข้าม "การพิมพ์เป็ด" หมายถึงการทำงานกับอินเทอร์เฟซทั่วไปมากกว่าการตรวจสอบประเภทอย่างชัดเจน ดังนั้นสิ่งที่ชอบif a == []คือการบังคับประเภทเฉพาะ ( () == []คือFalse) นี่ตกลงทั่วไปน่าจะเป็นที่การพิมพ์เป็ดชนะออก (ในผลบอกว่า__nonzero__เป็นอินเตอร์เฟซสำหรับการทดสอบความว่างเปล่าdocs.python.org/reference/datamodel.html#object.__nonzero__ )
แอนดรู Cooke

38
วิธีนี้ใช้ไม่ได้กับอาร์เรย์ numpy .. ดังนั้นฉันคิดว่า len (a) == 0 เป็นที่นิยมทั้งในแง่ของ "การพิมพ์เป็ด" และ implicitness
Mr.WorshipMe

10
วิธีบัญญัติของการรู้ว่าอาร์เรย์ใน C ว่างเปล่าหรือไม่โดยการยกเลิกการพิจารณาองค์ประกอบแรกและดูว่ามันเป็นโมฆะหรือไม่สมมติว่าอาร์เรย์ที่ถูกยกเลิก nul มิฉะนั้นการเปรียบเทียบความยาวของมันกับศูนย์จะไม่มีประสิทธิภาพอย่างสมบูรณ์ถ้าอาร์เรย์มีขนาดที่สำคัญ นอกจากนี้โดยทั่วไปคุณจะไม่จัดสรรหน่วยความจำสำหรับอาเรย์ที่ว่างเปล่า (ตัวชี้ยังคงเป็นโมฆะ) ดังนั้นจึงไม่มีเหตุผลที่จะลองความยาว ฉันไม่ได้บอกว่า len (a) == 0 ไม่ใช่วิธีที่ดีในการทำมันเพียงแค่ไม่กรีดร้อง 'C' กับฉันเมื่อฉันเห็นมัน
sleblanc

6
@BrennenSprimont ถ้าไม่ใช่โมฆะคุณก็รู้แล้วว่าความยาวไม่ว่ามันจะถูกเก็บไว้ในตัวแปรที่แยกจากกันหรืออาร์เรย์ของคุณถูกห่อในคอนเทนเนอร์ที่ติดตามความยาว C ++, Java, C # มีคอนเทนเนอร์ดังกล่าวและใช้วิธี "ความยาว" อย่างมีประสิทธิภาพ C ไม่มีสิ่งนั้นคุณต้องหมุนตัวเอง อาร์เรย์ C ที่จัดสรรแบบคงที่เป็นเพียงตัวชี้ไปยังพื้นที่หน่วยความจำที่รับประกันว่าจะมีพื้นที่เพียงพอที่จะเก็บจำนวนข้อมูลที่คุณร้องขอ ไม่มีสิ่งใดในตัว C ที่จะทำให้คุณรู้ว่าคุณได้เติมเต็มพื้นที่นั้นแล้ว
sleblanc

1158

วิธี pythonic ที่จะทำคือจากคู่มือสไตล์ PEP 8 (ที่ใช่หมายถึง "แนะนำ" และไม่ได้หมายความว่า "ไม่แนะนำ"):

สำหรับซีเควนซ์ (สตริง, รายการ, สิ่งอันดับ) ให้ใช้ความจริงที่ว่าลำดับที่ว่างเปล่าเป็นเท็จ

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):

49
วิธีที่สองดูดีกว่าหากคุณต้องการส่งสัญญาณที่seqคาดว่าจะเป็นวัตถุคล้ายรายการ
BallpointBen

5
@ BallpointBen ซึ่ง Pythonism advocate พูดว่าควรบอกเป็นนัยถึงการตั้งชื่อตัวแปรให้มากที่สุด
axolotl

9
@BallpointBen ลองใช้คำใบ้ประเภทของ Python เพื่อส่งสัญญาณว่าตัวแปรควรเป็นอย่างไร มันถูกนำมาใช้ใน 3.5
บอริส

8
numpy ทำให้สำนวนนี้เสียหาย ... seq = numpy.array ([1,2,3]) ตามด้วยถ้าไม่ใช่ seq จะทำให้เกิดข้อยกเว้น "ValueError: ค่าความจริงของอาร์เรย์ที่มีองค์ประกอบมากกว่าหนึ่งรายการไม่ชัดเจนใช้ a.any () หรือ a.all () "
Mr.WorshipMe

2
@eronimo: ฉันเชื่อว่านั่นเป็นคำเตือนเฉพาะ lxml
Harley Holcombe

767

ฉันชอบมันมาก:

if len(li) == 0:
    print('the list is empty')

วิธีนี้ชัดเจน 100% ซึ่งliเป็นลำดับ (รายการ) และเราต้องการทดสอบขนาดของมัน ปัญหาของฉันif not li: ...คือมันให้การแสดงผลที่ผิดพลาดซึ่งliเป็นตัวแปรบูลีน


91
การตรวจสอบว่าความยาวของรายการเท่ากับศูนย์หรือไม่แทนที่จะตรวจสอบว่ารายการนั้นเป็นเท็จหรือไม่นั้นน่าเกลียดและไม่ไพเราะ ใครก็ตามที่คุ้นเคยกับ Python จะไม่คิดว่าliเป็นคนโง่และไม่สนใจ หากเป็นสิ่งสำคัญคุณควรเพิ่มความคิดเห็นไม่ใช่รหัสเพิ่มเติม
Carl Smith

21
ดูเหมือนว่าจะเป็นการทดสอบที่ไม่จำเป็นซึ่งมักจะช้ากว่าและมักจะน้อยกว่า IMHO แทนที่จะตรวจสอบขนาดของบางสิ่งบางอย่างที่ว่างเปล่าทำไมไม่เพียงตรวจสอบว่ามันว่างเปล่า?
John B

34
อย่างไรก็ตามเหตุผลนี้ไม่ดี (และการละเมิดสำนวนในภาษาที่มีสำนวนที่รุนแรงเช่น Python ไม่ดีโดยทั่วไป) คือมันส่งสัญญาณไปยังผู้อ่านว่าคุณกำลังตรวจสอบความยาวด้วยเหตุผลบางประการ (เช่นเนื่องจากคุณต้องการNoneหรือ0เพื่อเพิ่มข้อยกเว้นแทนที่จะผ่าน) ดังนั้นเมื่อคุณทำโดยไม่มีเหตุผลนั่นก็ทำให้เข้าใจผิด - และมันก็หมายความว่าเมื่อรหัสของคุณไม่จำเป็นที่จะต้องสร้างความแตกต่างความแตกต่างจะมองไม่เห็นเพราะคุณได้ "หมาป่าร้องไห้" ทั้งหมดในส่วนที่เหลือของแหล่งที่มา
abarnert

18
ฉันคิดว่านี่เป็นเพียงแค่การเพิ่มความยาวรหัส มิฉะนั้นทำไมไม่ "ชัดเจน" มากขึ้นด้วยif bool(len(li) == 0) is True:?
augurar

11
@ Jabba มันจะเป็นO (1)ในหลาย ๆ กรณี (ที่ที่คุณทำงานกับชนิดข้อมูลในตัว) แต่คุณไม่สามารถวางใจได้ คุณอาจทำงานกับประเภทข้อมูลที่กำหนดเองที่ไม่มีคุณสมบัตินี้ คุณอาจตัดสินใจเพิ่มประเภทข้อมูลที่กำหนดเองนี้ในภายหลังหลังจากที่คุณเขียนรหัสนี้แล้ว
ralokt

324

นี่เป็น google hit ครั้งแรกสำหรับ "python test empty array" และข้อความค้นหาที่คล้ายกันรวมถึงคนอื่น ๆ ดูเหมือนจะสรุปคำถามที่นอกเหนือจากรายการเพียงอย่างเดียวดังนั้นฉันคิดว่าฉันจะเพิ่ม caveat สำหรับลำดับที่แตกต่างกันซึ่งผู้คนจำนวนมาก อาจใช้

วิธีอื่น ๆ ใช้ไม่ได้กับอาร์เรย์ NumPy

คุณต้องระมัดระวังกับอาร์เรย์ NumPy เนื่องจากวิธีการอื่นที่ทำงานได้ดีสำหรับlists หรือคอนเทนเนอร์มาตรฐานอื่น ๆ ล้มเหลวสำหรับอาร์เรย์ NumPy ฉันอธิบายว่าทำไมด้านล่าง แต่ในระยะสั้นที่วิธีการที่ต้องการsizeคือการใช้งาน

วิธี "pythonic" ไม่ทำงาน: ส่วนที่ 1

วิธี "pythonic" ล้มเหลวด้วย NumPy arrays เพราะ NumPy พยายามที่จะส่งอาเรย์ไปยังอาเรย์ของbools และif xพยายามที่จะประเมินทั้งหมดของbools ในเวลาเดียวกันสำหรับค่าความจริงรวมบางอย่าง แต่นี่ไม่มีเหตุผลใด ๆ ดังนั้นคุณจะได้รับValueError:

>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

วิธี "pythonic" ไม่ทำงาน: ส่วนที่ 2

แต่อย่างน้อยกรณีข้างต้นบอกคุณว่ามันล้มเหลว หากคุณมีอาร์เรย์ NumPy ที่มีองค์ประกอบหนึ่งรายการifคำสั่งจะ "ทำงาน" ในแง่ที่ว่าคุณไม่ได้รับข้อผิดพลาด อย่างไรก็ตามหากองค์ประกอบนั้นเกิดขึ้นเป็น0(หรือ0.0, หรือFalse, ... ) ifคำสั่งจะส่งผลให้ไม่ถูกต้องFalse:

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

แต่xมีอยู่อย่างชัดเจนและไม่ว่างเปล่า! ผลลัพธ์นี้ไม่ใช่สิ่งที่คุณต้องการ

การใช้lenสามารถให้ผลลัพธ์ที่ไม่คาดคิด

ตัวอย่างเช่น,

len( numpy.zeros((1,0)) )

ส่งคืน 1 แม้ว่าอาร์เรย์จะมีองค์ประกอบเป็นศูนย์

วิธีการทาง numpythonic

ตามที่อธิบายไว้ในSciPy FAQวิธีที่ถูกต้องในทุกกรณีที่คุณรู้ว่าคุณมีอาร์เรย์ NumPy คือการใช้if x.size:

>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x

หากคุณไม่แน่ใจว่าอาจเป็น A list, A , NumPy array หรืออย่างอื่นคุณสามารถรวมวิธีการนี้เข้ากับคำตอบที่ @dubiousjim ให้เพื่อให้แน่ใจว่ามีการใช้การทดสอบที่ถูกต้องสำหรับแต่ละประเภท ไม่ "pythonic" มากนัก แต่ปรากฎว่า NumPy จงใจทำลาย pythonicity อย่างน้อยก็ในแง่นี้

หากคุณจำเป็นต้องทำมากกว่าเพียงแค่ตรวจสอบว่าเข้าเป็นที่ว่างเปล่าและคุณกำลังใช้อื่น ๆ NumPy คุณสมบัติเช่นการจัดทำดัชนีหรือคณิตศาสตร์การดำเนินงานก็อาจจะมีประสิทธิภาพมากขึ้น (และแน่นอนร่วมกันมากขึ้น) เพื่อบังคับให้การป้อนข้อมูลจะเป็นอาร์เรย์ NumPy มีฟังก์ชั่นที่ดีบางประการสำหรับการทำเช่นนี้ได้อย่างรวดเร็ว - numpy.asarrayที่สำคัญที่สุด นี้จะใช้เวลาการป้อนข้อมูลของคุณไม่ทำอะไรเลยถ้ามันมีอยู่แล้วอาร์เรย์หรือตัดการป้อนข้อมูลของคุณลงในอาร์เรย์ถ้าหากมันเป็นรายการ tuple ฯลฯ dtypeและเลือกแปลงไปยังที่คุณเลือก ดังนั้นจึงเป็นไปได้อย่างรวดเร็วมากเมื่อใดก็ตามที่เป็นไปได้และทำให้มั่นใจได้ว่าคุณจะได้รับการป้อนข้อมูลเป็นอาร์เรย์ NumPy เรามักจะใช้ชื่อเดียวกันเนื่องจากการแปลงไปยังอาร์เรย์จะไม่ทำให้มันกลับมานอกขอบเขตปัจจุบัน:

x = numpy.asarray(x, dtype=numpy.double)

นี่จะทำให้การx.sizeตรวจสอบใช้งานได้ในทุกกรณีที่ฉันเห็นในหน้านี้


62
เป็นที่น่าสังเกตว่านี่ไม่ใช่ข้อบกพร่องใน Python แต่เป็นการผิดสัญญาโดยเจตนาnumpy- numpyเป็นห้องสมุดที่มีกรณีการใช้งานที่เฉพาะเจาะจงมากและมีคำจำกัดความ 'ธรรมชาติ' ที่แตกต่างกันของความจริงในอาเรย์ Python มาตรฐานสำหรับตู้คอนเทนเนอร์ มันสมเหตุสมผลที่จะปรับให้เหมาะสมสำหรับกรณีนั้นในลักษณะที่pathlibใช้/ในการเชื่อมโยงเส้นทางแทนที่จะเป็น+- มันไม่ได้มาตรฐาน แต่สมเหตุสมผลในบริบท
Gareth Latty

9
ตกลง ประเด็นของฉันก็คือมันเป็นสิ่งสำคัญที่ต้องจำไว้ว่า numpy ได้เลือกที่จะทำลายการพิมพ์เป็ดสำหรับทั้งสามัญif xและlen(x)สำนวน - และบางครั้งความแตกแยกนั้นยากที่จะตรวจจับและตรวจแก้จุดบกพร่อง
Mike

22
ฉันไม่รู้สำหรับฉันถ้าวิธีที่เรียกว่า len (x) ไม่ส่งคืนความยาวของอาเรย์เนื่องจากข้อสมมุติว่าชื่อนั้นออกแบบมาไม่ดี
ดาลตัน

11
คำถามนี้ไม่เกี่ยวข้องกับอาร์เรย์ numpy
pppery

19
@ppperry ใช่คำถามดั้งเดิมไม่ได้เกี่ยวกับอาร์เรย์ Numpy แต่เมื่อทำงานกับข้อโต้แย้งที่พิมพ์เหล่านั้นและอาจเป็นไปได้ที่เป็ดคำถามนี้มีความเกี่ยวข้องมาก
peterhil

223

วิธีที่ดีที่สุดในการตรวจสอบว่ารายการว่างเปล่า

ตัวอย่างเช่นหากผ่านสิ่งต่อไปนี้:

a = []

ฉันจะตรวจสอบเพื่อดูว่ามีอะไรว่างเปล่าได้อย่างไร

คำตอบสั้น ๆ :

วางรายการในบริบทบูลีน (ตัวอย่างเช่นด้วยคำสั่งifหรือwhile) มันจะทดสอบFalseว่ามันว่างเปล่าและTrueอื่น ๆ ตัวอย่างเช่น:

if not a:                           # do this!
    print('a is an empty list')

PEP 8

PEP 8คู่มือแนะนำอย่างเป็นทางการของ Python สำหรับโค้ด Python ในไลบรารี่มาตรฐานของ Python ที่อ้างถึง:

สำหรับซีเควนซ์ (สตริง, รายการ, สิ่งอันดับ) ให้ใช้ความจริงที่ว่าลำดับที่ว่างเปล่าเป็นเท็จ

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

เราควรคาดหวังว่ารหัสไลบรารีมาตรฐานควรมีประสิทธิภาพและถูกต้องที่สุด แต่ทำไมเป็นเช่นนั้นและทำไมเราถึงต้องการแนวทางนี้

คำอธิบาย

ฉันมักจะเห็นโค้ดเช่นนี้จากโปรแกรมเมอร์ที่มีประสบการณ์ใหม่ไปจนถึง Python:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

และผู้ใช้ภาษาขี้เกียจอาจถูกล่อลวงให้ทำเช่นนี้:

if a == []:                         # Don't do this!
    print('a is an empty list')

สิ่งเหล่านี้ถูกต้องในภาษาอื่น ๆ ที่เกี่ยวข้อง และสิ่งนี้ก็ถูกต้องทางความหมายใน Python

แต่เราถือว่ามันไม่เป็น Pythonic เพราะ Python สนับสนุนซีแมนทิกส์เหล่านี้โดยตรงในส่วนต่อประสานของวัตถุรายการผ่านการบังคับแบบบูล

จากเอกสาร (และบันทึกการรวมรายการว่างไว้โดยเฉพาะ[]):

โดยค่าเริ่มต้นวัตถุจะถือว่าเป็นจริงเว้นแต่ว่าระดับของมันจะกำหนด__bool__()วิธีการที่จะส่งกลับFalseหรือ__len__()วิธีการที่ส่งกลับศูนย์เมื่อเรียกกับวัตถุ นี่คือส่วนใหญ่ของวัตถุในตัวถือว่าเป็นเท็จ:

  • ค่าคงที่กำหนดเป็นเท็จ: NoneและFalseและ
  • ศูนย์ประเภทตัวเลขใด ๆ : 0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • ลำดับที่ว่างเปล่าและคอลเลกชัน: '', (), [], {}, set(),range(0)

และเอกสารข้อมูลแบบจำลอง:

object.__bool__(self)

เรียกว่าการดำเนินการทดสอบค่าความจริงและตัวในการดำเนินงานbool(); ควรกลับหรือFalse Trueเมื่อไม่ได้กำหนดเมธอดนี้จะ __len__()ถูกเรียกใช้หากถูกกำหนดไว้และอ็อบเจ็กต์นั้นถูกพิจารณาว่าเป็นจริงถ้าผลลัพธ์ของมันไม่ใช่ศูนย์ หากมีการกำหนดระดับค่า__len__() มิได้__bool__()อินสแตนซ์ทั้งหมดได้รับการพิจารณาความจริง

และ

object.__len__(self)

เรียกว่าใช้งานฟังก์ชันในlen()ตัว ควรคืนความยาวของวัตถุเป็นจำนวนเต็ม> = 0 นอกจากนี้วัตถุที่ไม่ได้กำหนด__bool__()วิธีการและ__len__()วิธีการที่ส่งกลับค่าศูนย์จะถือว่าเป็นเท็จในบริบทบูลีน

ดังนั้นแทนที่จะเป็นเช่นนี้:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

หรือสิ่งนี้:

if a == []:                     # Don't do this!
    print('a is an empty list')

ทำเช่นนี้:

if not a:
    print('a is an empty list')

ทำในสิ่งที่ Pythonic มักจ่ายให้ในการแสดง:

มันจ่ายออกหรือไม่ (โปรดทราบว่าใช้เวลาน้อยกว่าในการดำเนินการเทียบเท่าจะดีกว่า :)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

สำหรับมาตราส่วนนี่คือค่าใช้จ่ายในการเรียกใช้ฟังก์ชันและการสร้างและส่งคืนรายการเปล่าซึ่งคุณอาจลบออกจากค่าใช้จ่ายของการตรวจสอบความว่างเปล่าที่ใช้ด้านบน:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

เราจะเห็นว่าทั้งการตรวจสอบสำหรับความยาวที่มีฟังก์ชั่นในตัวlenเมื่อเทียบกับ0 หรือตรวจสอบกับรายการที่ว่างเปล่าเป็นมากน้อย performant กว่าการใช้ไวยากรณ์ในตัวของภาษาที่เป็นเอกสาร

ทำไม?

สำหรับการ len(a) == 0ตรวจสอบ:

Python แรกจะต้องตรวจสอบ globals เพื่อดูว่า lenมีเงาหรือไม่

จากนั้นจะต้องเรียกใช้ฟังก์ชันโหลด0และทำการเปรียบเทียบความเท่าเทียมกันใน Python (แทนที่จะใช้ C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

และสำหรับ[] == []มันจะต้องสร้างรายการที่ไม่จำเป็นจากนั้นทำการเปรียบเทียบในเครื่องเสมือนของ Python อีกครั้ง (ตรงข้ามกับ C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

วิธี "Pythonic" เป็นการตรวจสอบที่ง่ายและเร็วขึ้นเนื่องจากความยาวของรายการถูกแคชไว้ในส่วนหัวของอินสแตนซ์ของวัตถุ:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

หลักฐานจากแหล่ง C และเอกสารประกอบ

PyVarObject

นี่คือส่วนขยายของPyObjectที่เพิ่มob_sizeเขตข้อมูล ใช้สำหรับวัตถุที่มีความยาวเท่ากัน ประเภทนี้มักจะไม่ปรากฏใน Python / C API มันสอดคล้องกับเขตข้อมูลที่กำหนดโดยการขยายตัวของPyObject_VAR_HEADแมโคร

จากแหล่ง c ในรวม / listobject.h :

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

การตอบสนองต่อความคิดเห็น:

ผมจะชี้ให้เห็นว่าเรื่องนี้ก็เป็นจริงสำหรับกรณีที่ไม่ว่างเปล่า แต่ที่น่าเกลียดสวยเช่นเดียวกับl=[]แล้ว%timeit len(l) != 090.6 ± 8.3 NS NS, %timeit l != []55.6 NS ± 3.09, %timeit not not l38.5 NS ± 0.372 แต่ไม่มีทางที่ทุกคนจะเพลิดเพลินไปกับnot not lความเร็วสามเท่า มันดูไร้สาระ แต่ความเร็วที่ชนะ
ฉันคิดว่าปัญหาคือการทดสอบด้วย timeit เนื่องจากif l:มีเพียงพอ แต่%timeit bool(l)ให้ผลที่น่าประหลาดใจ101 ns ± 2.64 ns ที่น่าสนใจไม่มีทางที่จะบีบบังคับให้บูลโดยไม่มีการลงโทษนี้ %timeit lไม่มีประโยชน์เนื่องจากไม่มีการแปลงเกิดขึ้น

มายากล IPython %timeitนั้นไม่ได้ไร้ประโยชน์เลยที่นี่:

In [1]: l = []                                                                  

In [2]: %timeit l                                                               
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [3]: %timeit not l                                                           
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not l                                                       
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

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

In [5]: %timeit if l: pass                                                      
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [6]: %timeit if not l: pass                                                  
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit if not not l: pass                                              
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

ตอนนี้ลองดูกรณีสำหรับรายการที่ไม่มีข้อยกเว้น:

In [8]: l = [1]                                                                 

In [9]: %timeit if l: pass                                                      
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [10]: %timeit if not l: pass                                                 
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit if not not l: pass                                             
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

สิ่งที่เราสามารถเห็นได้จากที่นี่คือมันสร้างความแตกต่างเล็กน้อยไม่ว่าคุณจะผ่านการboolตรวจสอบสภาพจริงหรือรายชื่อตัวเองและถ้ามีอะไรก็ตาม

Python เขียนด้วย C; มันใช้ตรรกะที่ระดับ C สิ่งที่คุณเขียนด้วย Python จะช้าลง และมันอาจเป็นคำสั่งที่มีขนาดช้ากว่าถ้าคุณไม่ได้ใช้กลไกที่สร้างไว้ใน Python โดยตรง


ผมจะชี้ให้เห็นว่าเรื่องนี้ก็เป็นจริงสำหรับกรณีที่ไม่ว่างเปล่า แต่ที่น่าเกลียดสวยเช่นเดียวกับl=[]แล้ว%timeit len(l) != 090.6 ± 8.3 NS NS, %timeit l != []55.6 NS ± 3.09, %timeit not not l38.5 NS ± 0.372 แต่ไม่มีทางที่ทุกคนจะเพลิดเพลินไปกับnot not lความเร็วสามเท่า มันดูไร้สาระ แต่ความเร็วชนะออกมา
Gregory Morse

ฉันคิดว่าปัญหาคือการทดสอบด้วย timeit เนื่องจากif l:มีเพียงพอ แต่%timeit bool(l)ให้ผลที่น่าประหลาดใจ101 ns ± 2.64 ns ที่น่าสนใจไม่มีทางที่จะบีบบังคับให้บูลโดยไม่มีการลงโทษนี้ %timeit lไม่มีประโยชน์เนื่องจากไม่มีการแปลงเกิดขึ้น
เกรกอรี่มอร์ส

138

รายการเปล่าถือว่าเป็นเท็จในการทดสอบค่าจริง (ดูเอกสารหลาม ):

a = []
if a:
     print "not empty"

@Daren Thomas

แก้ไข: อีกจุดหนึ่งที่ต่อต้านการทดสอบรายการที่ว่างเปล่าว่าเป็นเท็จ: แล้วความหลากหลายนั้นเป็นอย่างไร คุณไม่ควรขึ้นอยู่กับรายการที่เป็นรายการ มันควรจะต้มตุ๋นเหมือนเป็ด - คุณจะได้รับเป็ดของคุณได้อย่างไรการต้มตุ๋น '' เท็จ '' เมื่อมันไม่มีองค์ประกอบ?

DuckCollection ของคุณควรนำไปใช้__nonzero__หรือ__len__ถ้า a: จะทำงานได้โดยไม่มีปัญหา


แปลก ๆ ว่า[] == Falseจะประเมินผลเป็นเท็จได้อย่างไร
information_interchange

@information_interchange ถ้าคุณต้องการที่จะตรวจสอบอย่างชัดเจน truthiness bool()ของค่าการใช้งาน bool([]) == Falseจะประเมินให้Trueเป็นไปตามที่คาดไว้
augurar

103

คำตอบ (ยอมรับ) ของ Patrickนั้นถูกต้อง: if not a:เป็นวิธีที่เหมาะสมที่จะทำ คำตอบของ Harley Holcombeนั้นถูกต้องว่านี่เป็นแนวทางใน PEP 8 แต่ไม่มีคำตอบใดที่อธิบายได้ว่าทำไมมันเป็นความคิดที่ดีที่จะทำตามสำนวน - แม้ว่าคุณจะพบว่ามันไม่ชัดเจนหรือสับสนกับผู้ใช้ Ruby หรืออะไรก็ตาม

รหัส Python และชุมชน Python มีสำนวนที่แข็งแกร่งมาก การทำตามสำนวนเหล่านั้นทำให้โค้ดของคุณอ่านง่ายขึ้นสำหรับทุกคนที่มีประสบการณ์ใน Python และเมื่อคุณละเมิดสำนวนเหล่านั้นนั่นเป็นสัญญาณที่ดี

เป็นความจริงที่if not a:ไม่แยกความแตกต่างของรายการที่ว่างเปล่าNoneหรือตัวเลข 0 หรือ tuples ที่ว่างเปล่าหรือประเภทคอลเลกชันที่ผู้ใช้สร้างขึ้นหรือประเภทที่ไม่ได้สร้างขึ้นโดยผู้ใช้ที่ว่างเปล่าหรืออาร์เรย์ NumPy องค์ประกอบเดียวที่ทำหน้าที่เป็นสเกลา ค่านิยม ฯลฯ และบางครั้งสิ่งสำคัญคือต้องมีความชัดเจนเกี่ยวกับเรื่องนั้น และในกรณีนี้คุณรู้ว่าคุณต้องการชัดเจนอะไรเพื่อให้คุณสามารถทดสอบได้อย่างชัดเจน ตัวอย่างเช่นif not a and a is not None:หมายถึง "อะไรที่ผิดพลาดยกเว้นไม่มี" ในขณะที่if len(a) != 0:หมายถึง "เฉพาะลำดับที่ว่างเปล่า - และสิ่งอื่น ๆ นอกเหนือจากลำดับคือข้อผิดพลาดที่นี่" และอื่น ๆ นอกจากการทดสอบสิ่งที่คุณต้องการทดสอบแล้วสิ่งนี้ยังส่งสัญญาณไปยังผู้อ่านว่าการทดสอบนี้มีความสำคัญ

แต่เมื่อคุณไม่มีอะไรที่ชัดเจนเกี่ยวกับสิ่งอื่นใดนอกเหนือจากการif not a:หลอกลวงผู้อ่าน คุณกำลังส่งสัญญาณบางสิ่งที่สำคัญเมื่อมันไม่ได้เป็น (คุณยังอาจจะทำให้รหัสที่มีความยืดหยุ่นน้อยกว่าหรือช้ากว่าหรืออะไรก็ตาม แต่นั่นคือทั้งหมดที่มีความสำคัญน้อย.) และถ้าคุณเป็นประจำทำให้เข้าใจผิดของผู้อ่านเช่นนี้แล้วเมื่อคุณทำจำเป็นที่จะต้องสร้างความแตกต่างก็จะผ่านเพราะไม่มีใครสังเกตเห็น คุณได้รับ "ร้องไห้หมาป่า" ทั่วรหัสของคุณ


78

ทำไมต้องตรวจสอบทั้งหมด

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

ฉันจะเถียงว่าวิธีที่ไพทอนที่สุดคือการไม่ตรวจสอบเลย แต่เป็นการประมวลผลรายการ ด้วยวิธีนี้มันจะทำสิ่งที่ถูกต้องไม่ว่าจะว่างเปล่าหรือเต็ม

a = []

for item in a:
    <do something with item>

<rest of code>

สิ่งนี้มีประโยชน์ในการจัดการกับเนื้อหาใด ๆ ของaในขณะที่ไม่ต้องการการตรวจสอบความว่างเปล่าโดยเฉพาะ หากaว่างเปล่าบล็อกที่ขึ้นต่อกันจะไม่ถูกดำเนินการและล่ามจะผ่านไปยังบรรทัดถัดไป

หากคุณต้องการตรวจสอบความว่างเปล่าของอาร์เรย์คำตอบอื่น ๆ ก็เพียงพอแล้ว


3
สิ่งคือตรวจสอบว่ารายการว่างเปล่ามีความสำคัญอย่างน้อยสำหรับฉัน คุณได้พิจารณาแล้วว่ามีสคริปต์อยู่ข้างใน<rest of code>ที่อาจใช้ผลลัพธ์จากการforวนซ้ำหรือไม่? โดยตรงหรือใช้ค่าบางอย่างในa? แน่นอนถ้าสคริปต์ถูกออกแบบให้ทำงานด้วยอินพุตที่ควบคุมอย่างเข้มงวดการตรวจสอบอาจไม่จำเป็นเพียงเล็กน้อย แต่ในกรณีส่วนใหญ่อินพุตจะแตกต่างกันและการตรวจสอบมักจะดีกว่า
Amarth Gûl

ขอแสดงความนับถือ สิ่งที่ฉันถือว่าเป็นคนที่ไม่รู้จัก Python มากพอที่จะรู้ว่า“ ถ้า <list>:” เป็นคำตอบที่ถูกต้องให้ถามวิธีตรวจสอบรายการว่าง จากนั้นฉันสังเกตเห็นคำตอบมากมายที่เสนอความคิดเห็นต่างกัน แต่ดูเหมือนไม่มีใครตอบความต้องการเดิม นั่นคือสิ่งที่ฉันพยายามทำกับคำตอบของฉัน - ให้พวกเขาตรวจสอบความต้องการก่อนดำเนินการต่อ ฉันเชื่อว่าฉันแนะนำมากในคำตอบของฉันอย่างชัดเจน
MrWonderful

@ AmarthGûl - วิธีหนึ่งอาจได้รับผลลัพธ์จากการ for วนไปยังสคริปต์ภายใน <ส่วนที่เหลือของรหัส> ที่จะประมวลผล? ในรายการบางที? หรืออาจเป็นคำพูด? ถ้าเป็นเช่นนั้นจะใช้ตรรกะเดียวกัน ฉันไม่เข้าใจว่าการป้อนข้อมูลแบบแปรผันอาจมีผลกระทบใด ๆ ภายในรหัสที่ออกแบบมาอย่างสมเหตุสมผลการประมวลผลรายการที่ว่างเปล่าจะเป็นความคิดที่ไม่ดี
MrWonderful

ค่อนข้างเก่า แต่ถ้าคุณเพิ่งตรวจสอบว่ารายการนั้นว่างเปล่าหรือเปล่าสำหรับรายการที่ไม่ว่างเปล่ารหัสของคุณจะทำซ้ำกระบวนการซ้ำแล้วซ้ำอีกเมื่อ OP กำลังมองหาการดำเนินการตรวจสอบ ลองจินตนาการถึงสถานการณ์ที่เลวร้ายสำหรับโค้ดนั้นเมื่อ n เข้าใกล้อนันต์ ....
DJK

7
@DJK - ไม่ฉันคิดว่าคุณยังคิดถึงอยู่ดี สมมุติว่าคุณต้องการทำบางสิ่งบางอย่างกับรายการถ้าคุณมี คุณจะทำอะไรที่แตกต่างถ้าว่างเปล่า? กลับก่อนไหม เกิดอะไรขึ้นถ้ามันไม่ว่างเปล่า ดำเนินการหรือไม่ ประเด็นก็คือว่าคุณอาจไม่จำเป็นต้องตรวจสอบรายการว่างเปล่าแค่วนซ้ำและทำสิ่งที่คุณจะทำกับองค์ประกอบ หากไม่มีองค์ประกอบคุณจะล้มเหลว หากมีองค์ประกอบคุณจะดำเนินการตามที่คุณต้องการ จุดคือไม่ใช้ตัวอย่างสำหรับการตรวจสอบที่ว่างเปล่า แต่แทนที่จะไม่ตรวจสอบเลยเพียงแค่ดำเนินการรายการ
MrWonderful


40

ฉันได้เขียน:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

ซึ่งได้รับการโหวต -1 ฉันไม่แน่ใจว่าเป็นเพราะผู้อ่านคัดค้านกลยุทธ์หรือคิดว่าคำตอบนั้นไม่เป็นประโยชน์ตามที่นำเสนอ ฉันจะแกล้งทำเป็นว่ามันเป็นช่วงหลังตั้งแต่ --- อะไรก็ตามที่นับว่าเป็น "pythonic" --- นี่คือกลยุทธ์ที่ถูกต้อง ยกเว้นว่าคุณได้ตัดออกไปแล้วหรือเตรียมรับมือกับกรณีที่aเป็นเช่นFalseนั้นคุณต้องมีการทดสอบที่เข้มงวดมากกว่าเพียงแค่if not a:นั้น คุณสามารถใช้สิ่งนี้:

if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff

การทดสอบครั้งแรกเป็นการตอบสนองต่อคำตอบของ @ Mike ด้านบน บรรทัดที่สามอาจถูกแทนที่ด้วย:

elif isinstance(a, (list, tuple)) and not a:

หากคุณต้องการที่จะยอมรับอินสแตนซ์ของประเภทเฉพาะ (และประเภทย่อย) หรือด้วย:

elif isinstance(a, (list, tuple)) and not len(a):

คุณสามารถออกไปได้โดยไม่ต้องมีการตรวจสอบประเภทอย่างชัดเจน แต่ถ้าบริบทโดยรอบแล้วทำให้คุณมั่นใจว่าaเป็นค่าของประเภทที่คุณเตรียมไว้ให้จัดการหรือถ้าคุณแน่ใจว่าประเภทที่คุณไม่พร้อมจะจัดการนั้นกำลังดำเนินอยู่ เพื่อเพิ่มข้อผิดพลาด (เช่นTypeErrorถ้าคุณโทรหาlenค่าที่ไม่ได้กำหนดไว้) ที่คุณเตรียมไว้ให้จัดการ โดยทั่วไปการประชุม "pythonic" ดูเหมือนจะเป็นวิธีสุดท้าย บีบมันเหมือนเป็ดแล้วปล่อยมันขึ้นมา DuckError ถ้าไม่รู้วิธีต้มตุ๋น คุณยังคงต้องคิดเกี่ยวกับประเภทของสมมติฐานที่คุณกำลังทำอยู่และไม่ว่ากรณีที่คุณไม่ได้เตรียมที่จะรับมืออย่างถูกต้องนั้นจะเกิดข้อผิดพลาดในที่ที่เหมาะสมหรือไม่ อาร์เรย์ Numpy เป็นตัวอย่างที่ดีที่พึ่งพึ่งการสุ่มสี่สุ่มห้าlen หรือ typecast บูลีนอาจทำสิ่งที่คุณคาดหวังไม่แม่นยำ


3
มันค่อนข้างยากที่คุณจะมีรายการทั้งหมด 6 แบบที่คุณต้องการยอมรับและไม่ยืดหยุ่นสำหรับประเภทอื่น ๆ เมื่อคุณต้องการสิ่งนั้นคุณอาจต้องการ ABC ในกรณีนี้มันอาจจะเป็นหนึ่งใน stdlib ABCs อย่างเช่นcollections.abc.Sizedหรือcollections.abc.Sequenceแต่มันอาจจะเป็นสิ่งที่คุณเขียนเองและregister(list)ต่อไป หากคุณมีรหัสซึ่งเป็นสิ่งสำคัญที่จะต้องแยกความแตกต่างที่ว่างเปล่าจากความผิดพลาดอื่น ๆ และเพื่อแยกความแตกต่างของรายการและสิ่งอันดับจากลำดับอื่น ๆ สิ่งนี้ถูกต้อง - แต่ฉันไม่เชื่อว่าคุณมีรหัสดังกล่าว
abarnert

13
เหตุผลที่คนไม่ชอบสิ่งนี้เป็นเพราะในกรณีส่วนใหญ่ unnessesary Python เป็นภาษาที่พิมพ์ด้วยเป็ดและการเข้ารหัสระดับนี้เป็นอุปสรรคต่อสิ่งนั้น แนวคิดเบื้องหลังระบบชนิดของ Python คือสิ่งที่ควรทำงานตราบเท่าที่วัตถุผ่านไปในฟังก์ชั่นในแบบที่มันต้องการ เมื่อทำการตรวจสอบประเภทอย่างชัดเจนคุณกำลังบังคับให้ผู้เรียกใช้ชนิดที่เจาะจงขัดกับภาษาที่เป็นธัญพืช ในขณะที่บางสิ่งบางอย่างมีความจำเป็น (ไม่รวมสตริงจากการถือว่าเป็นลำดับ) กรณีเช่นนี้หายากและดีที่สุดในบัญชีดำ
Gareth Latty

1
หากคุณต้องการตรวจสอบว่าค่านั้นตรงกับความจริง[]และไม่ใช่สิ่งที่ผิดประเภทอื่น ๆ แน่นอนif a == []:ว่าถูกเรียกใช้แทนการล้อเล่นกับไอซิส
RemcoGerlich

2
มีบาง coercions อัตโนมัติสำหรับเป็น==แม้ว่า จากด้านบนของหัวฉันไม่สามารถระบุ[]ได้ ผลตอบแทนเช่น[] == () Falseแต่สำหรับตัวอย่างเช่นผลตอบแทนfrozenset()==set() Trueอย่างน้อยก็ให้ความคิดว่าประเภทที่ไม่พึงประสงค์บางประเภทอาจถูกข่มขู่ให้[](หรือกลับกัน) เมื่อทำเช่นa == []นั้น
dubiousjim

@RemcoGerlich - isinstance () ยังคงเป็นที่นิยมมากกว่าการสร้างรายการว่างเพื่อเปรียบเทียบ นอกจากนี้ยังมีอีกคนหนึ่งที่ชี้ให้เห็นว่าผู้ประกอบการความเท่าเทียมกันอาจก่อให้เกิดการแปลงโดยนัยในบางประเภทซึ่งอาจไม่พึงปรารถนา ไม่มีเหตุผลที่จะใช้รหัส "a == []" และรหัสนั้นจะถูกตั้งค่าสถานะเป็นข้อบกพร่องในการตรวจสอบรหัสใด ๆ ที่ฉันเข้าร่วมการใช้เครื่องมือที่เหมาะสมตามที่จัดทำโดยภาษาไม่ควรได้รับการพิจารณา " "แต่ค่อนข้าง" เทคนิคการเขียนโปรแกรมที่ดี "
MrWonderful

29

จากเอกสารเกี่ยวกับการทดสอบค่าความจริง:

ค่าทั้งหมดนอกเหนือจากที่แสดงไว้ที่นี่จะได้รับการพิจารณา True

  • None
  • False
  • ศูนย์ประเภทตัวเลขใด ๆ 0ตัวอย่างเช่น0.0, 0j,
  • ลำดับว่างใด ๆ ''ตัวอย่างเช่น(), [],
  • การทำแผนที่ว่างใด ๆ {}ยกตัวอย่างเช่น
  • อินสแตนซ์ของคลาสที่ผู้ใช้กำหนดถ้าคลาสกำหนด a __bool__()หรือ__len__()เมธอดเมื่อเมธอดนั้นส่งคืนค่าเลขศูนย์หรือค่าบูFalse

ดังที่เห็นได้รายการว่างเปล่า[]เป็นเท็จดังนั้นการทำสิ่งที่ควรทำกับค่าบูลีนฟังดูมีประสิทธิภาพมากที่สุด:

if not a:
    print('"a" is empty!')

@DJ_Stuffy_K ยืนยันว่ามีอะไรในการทดสอบหน่วยรายการว่างเปล่า assert(not myList)ใช้เพียงแค่ หากคุณยังต้องการที่จะยืนยันวัตถุนั้นเป็นคุณสามารถใช้list assertIsInstance()
Sнаđошƒаӽ

24

คุณสามารถตรวจสอบว่ารายการว่างเปล่าหรือไม่:

a = [] #the list

1)วิธี pythonic ที่ค่อนข้างเรียบง่าย:

if not a:
    print("a is empty")

ในหลาม, ภาชนะเปล่าเช่นรายการ tuples, ชุด dicts ตัวแปรอื่น ๆ Falseจะเห็นเป็น เราสามารถจัดการกับรายการเป็นเพรดิเคต ( ส่งคืนค่าบูลีน ) และTrueค่าจะบ่งบอกว่ามันไม่ว่างเปล่า

2)วิธีที่ชัดเจนมาก: การใช้len()เพื่อค้นหาความยาวและตรวจสอบว่ามันเท่ากับ0:

if len(a) == 0:
    print("a is empty")

3)หรือเปรียบเทียบกับรายการว่างที่ไม่ระบุชื่อ:

if a == []:
    print("a is empty")

4)อีกเลยโง่วิธีที่จะทำคือการใช้exceptionและiter():

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")

20

ฉันชอบสิ่งต่อไปนี้:

if a == []:
   print "The list is empty."

37
สิ่งนี้จะช้าลงในขณะที่คุณยกตัวอย่างรายการว่างเปล่าพิเศษโดยไม่จำเป็น
Carl Meyer

32
สิ่งนี้อ่านได้ง่ายกว่าif not a:และแตกหักง่ายกว่า โปรดอย่าทำ
devsnd

มีจุดดีที่ทำไว้ก่อนหน้า() == []นี้ยังเท่ากับเท็จ แม้ว่าฉันจะชอบวิธีการใช้งานนี้if not a:ครอบคลุมทุกกรณี แต่ถ้าคุณคาดหวังว่ารายการนั้นเป็นตัวอย่างที่ดีของคุณ
ดาว

19

วิธีที่ 1 (ที่ต้องการ):

if not a : 
   print ("Empty") 

วิธีที่ 2:

if len(a) == 0 :
   print( "Empty" )

วิธีที่ 3:

if a == [] :
  print ("Empty")

12
def list_test (L):
    if   L is None  : print('list is None')
    elif not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test(None)
list_test([])
list_test([1,2,3])

บางครั้งเป็นการดีที่จะทดสอบNoneและแยกว่างเปล่าเนื่องจากเป็นสถานะที่แตกต่างกันสองสถานะ รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้:

list is None 
list is empty 
list has 3 elements

แม้ว่ามันจะไม่มีค่าอะไรที่Noneเป็นเท็จ ดังนั้นหากคุณไม่ต้องการแยกการทดสอบเพื่อความNoneสมบูรณ์คุณไม่จำเป็นต้องทำเช่นนั้น

def list_test2 (L):
    if not L      : print('list is empty')
    else: print('list has %d elements' % len(L))

list_test2(None)
list_test2([])
list_test2([1,2,3])

คาดว่าจะผลิต

list is empty
list is empty
list has 3 elements

8

มีคำตอบมากมายและหลายคนก็ค่อนข้างดี ฉันแค่อยากจะเพิ่มการตรวจสอบว่า

not a

จะผ่านNoneและโครงสร้างที่ว่างเปล่าประเภทอื่น ๆ หากคุณต้องการตรวจสอบรายการว่างคุณสามารถทำสิ่งนี้ได้:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

เป็นไปได้ที่สิ่งนี้จะโยนข้อยกเว้นหากaไม่ใช่รายการและaไม่มีวิธีการ__len__ใช้ ฉันจะแนะนำ:if isinstance(obj, list): if len(obj) == 0: print '...'
Sven Krüger

4
@ SvenKrügerไม่ ผู้ประกอบการandขี้เกียจใน Python จะไม่มีการดำเนินการใด ๆ หลังจากandนั้นหากเงื่อนไขก่อนหน้าandนี้เป็นเท็จ
ElmoVanKielmo

7

เราสามารถใช้ง่ายถ้าอื่น:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")

5
-1 - เพื่อหลีกเลี่ยงความสับสนอย่าใช้คำสงวนสำหรับชื่อตัวแปรหรือคุณอาจมีพฤติกรรมที่น่าแปลกใจในครั้งต่อไปที่คุณพยายามโทรเช่น "list ()" ... บางอย่างเช่น "TypeError: 'list' object คือ ไม่สามารถเรียกได้ "หรือบางอย่าง
MrWonderful

6

หากคุณต้องการตรวจสอบว่ารายการว่างเปล่าหรือไม่:

l = []
if l:
    # do your stuff.

หากคุณต้องการตรวจสอบว่าค่าทั้งหมดในรายการว่างเปล่า อย่างไรก็ตามมันจะTrueเป็นรายการที่ว่างเปล่า:

l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.

หากคุณต้องการใช้ทั้งสองกรณีพร้อมกัน:

def empty_list(lst):
    if len(lst) == 0:
        return False
    else:
        return all(bool(x) for x in l)

ตอนนี้คุณสามารถใช้:

if empty_list(lst):
    # do your stuff.

1
ทั้งหมด (bool (x) สำหรับ x ใน l) เป็นจริงสำหรับรายการว่าง
gberger

5

ด้วยแรงบันดาลใจจากวิธีการแก้ปัญหาของ @dubiousjim ฉันเสนอให้ใช้การตรวจสอบทั่วไปเพิ่มเติมว่าเป็นสิ่งที่ทำซ้ำได้หรือไม่

import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)

หมายเหตุ: สตริงถูกพิจารณาว่าสามารถทำซ้ำได้ - เพิ่มand not isinstance(a,(str,unicode))ถ้าคุณต้องการยกเว้นสตริงว่างที่จะถูกแยกออก

ทดสอบ:

>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True

1
Overbroad; นี่เป็นเพียงการถามว่ารายการว่างเปล่าหรือไม่
pppery

1
ถ้าฉันไม่มีความสุขif a:ก็คงเป็นเพราะฉันต้องการข้อยกเว้นถ้าaไม่มีคอนเทนเนอร์ (การทำซ้ำยังช่วยให้ผู้ทำซ้ำซึ่งไม่สามารถทดสอบความว่างเปล่าได้อย่างเป็นประโยชน์)
Davis Herring

5
print('not empty' if a else 'empty')

ปฏิบัติมากขึ้นเล็กน้อย:

a.pop() if a else None

และรุ่นที่สั้นที่สุด:

if a: a.pop() 

4

ตั้งแต่ python3 เป็นต้นไปคุณสามารถใช้

a == []

เพื่อตรวจสอบว่ารายการว่างเปล่า

แก้ไข: มันใช้งานได้กับ python2.7 เช่นกัน

ฉันไม่แน่ใจว่าทำไมมีคำตอบที่ซับซ้อนมากมาย มันค่อนข้างชัดเจนและตรงไปตรงมา


1
โปรดอธิบายเพิ่มเติมเกี่ยวกับวิธีการทำงานโดยไม่ต้องเขียน "ถ้า"?
ganeshdeshmukh

3
นี่ไม่ใช่ pythonic หรือตัวอย่างที่สมบูรณ์ นอกจากนี้ยังเพิ่มรายการว่างทุกครั้งที่พบ อย่าทำอย่างนี้
MrWonderful

@MrWonderful มันไม่ได้ยกตัวอย่างรายการที่ว่างเปล่าทุกครั้ง มันแค่ตรวจสอบว่ารายการที่มีอยู่aว่างเปล่าหรือไม่
Tessaracter

@MrWonderful ฉันไม่ได้รับสิ่งที่ทำให้มันpythonic
Tessaracter

@ganeshdeshmukh ถ้าคุณใช้a==[]มันจะพิมพ์จริงบนเทอร์มินัลไพ ธ อนถ้า a ว่างเปล่า มิฉะนั้นจะพิมพ์ False คุณสามารถใช้สิ่งนี้ภายในเงื่อนไข if as asif(a==[])
Tessaracter

3

คุณสามารถลองใช้บูล () เช่นนี้

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

ฉันชอบวิธีนี้สำหรับการตรวจสอบรายการว่างเปล่าหรือไม่

มีประโยชน์มากและมีประโยชน์


4
สำหรับผู้ที่ไม่รู้จักให้bool()แปลงตัวแปร Python เป็นบูลีนเพื่อให้คุณสามารถเก็บค่าความจริงหรือความผิดพลาดของค่าโดยไม่ต้องใช้คำสั่ง if ฉันคิดว่ามันอ่านง่ายกว่าการใช้เงื่อนไขแบบเดียวกับคำตอบที่ยอมรับ แต่ฉันแน่ใจว่ามีกรณีการใช้ที่ดีอื่น ๆ
Galen Long

นี่คือการใช้งานในการแสดงออกและเป็นเรื่องย่อมากขึ้น
qneill

3

เพียงใช้ is_empty () หรือทำให้ฟังก์ชั่นที่ชอบ: -

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

มันสามารถใช้สำหรับ data_structure ใด ๆ เช่นรายการ tuples พจนานุกรมและอื่น ๆ อีกมากมาย is_empty(any_structure)โดยเหล่านี้คุณสามารถเรียกมันหลายครั้งโดยใช้เพียง


3
ชื่อis_emptyแนะนำว่าจะส่งคืนบางสิ่ง แต่ถ้าเป็นเช่นนั้นสิ่งนั้นจะเป็นbool(any_structure)สิ่งที่คุณควรใช้แทน ( เมื่อคุณต้องการboolเลย)
Davis Herring

4
ทำไมเราถึงต้องการรูปแบบที่หลากหลายbool(เช่น) พิมพ์ข้อความไปยังเอาต์พุตมาตรฐาน
Davis Herring

@DavisHerring เรามักจะมีสองตัวเลือกแรกคือการพิมพ์โดยใช้ฟังก์ชั่นอื่น ๆ คือการใช้boolตัวแปรส่งคืน ทางเลือกเป็นของคุณ ฉันเขียนทั้งสองเพื่อให้คุณสามารถเลือกระหว่างพวกเขา
Vineet Jain


1

ค่าความจริงของรายการที่ว่างเปล่าคือในขณะที่สำหรับรายการที่ไม่ว่างเปล่ามันเป็นFalseTrue


1

สิ่งที่นำฉันมาที่นี่คือกรณีใช้งานพิเศษ: ฉันต้องการให้ฟังก์ชันบอกฉันว่ารายการว่างเปล่าหรือไม่ ฉันต้องการหลีกเลี่ยงการเขียนฟังก์ชั่นของตัวเองหรือใช้การแสดงออกแลมบ์ดาที่นี่ (เพราะดูเหมือนว่ามันควรจะง่ายพอ):

foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))

และแน่นอนมีวิธีที่เป็นธรรมชาติมากที่จะทำ:

foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))

แน่นอนไม่ได้ใช้boolในif(คือif bool(L):) เพราะโดยนัย แต่สำหรับกรณีที่ "ไม่ว่าง" มีความจำเป็นอย่างชัดเจนว่าเป็นฟังก์ชั่นboolเป็นตัวเลือกที่ดีที่สุด


1

ในการตรวจสอบว่ารายการว่างเปล่าหรือไม่คุณสามารถใช้สองวิธีต่อไปนี้ แต่จำไว้ว่าเราควรหลีกเลี่ยงวิธีการตรวจสอบลำดับอย่างชัดเจน (เป็นless pythonicวิธี):

def enquiry(list1): 
    if len(list1) == 0: 
        return 0
    else: 
        return 1

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list isn't empty") 
else: 
    print("The list is Empty") 

# Result: "The list is Empty".

วิธีที่สองคือmore pythonicหนึ่ง วิธีนี้เป็นวิธีการตรวจสอบโดยนัยและเป็นที่นิยมมากกว่าวิธีก่อนหน้า

def enquiry(list1): 
    if not list1: 
        return True
    else: 
        return False

# ––––––––––––––––––––––––––––––––

list1 = [] 

if enquiry(list1): 
    print ("The list is Empty") 
else: 
    print ("The list isn't empty") 

# Result: "The list is Empty"

หวังว่านี่จะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.