ฉันจะตรวจสอบว่ามีสิ่งใด (ไม่) ในรายการใน Python ได้อย่างไร
วิธีที่ถูกที่สุดและอ่านง่ายที่สุดคือการใช้inโอเปอเรเตอร์ (หรือในกรณีเฉพาะของคุณnot in) ตามที่ระบุไว้ในเอกสาร
ผู้ประกอบการinและnot inทดสอบการเป็นสมาชิก x in sประเมิน
Trueว่าหากxเป็นสมาชิกของsและFalseอื่น ๆ ผลตอบแทนของการปฏิเสธx not in sx in s
นอกจากนี้
ผู้ประกอบการที่มีการกำหนดให้มีมูลค่าที่แท้จริงผกผันของnot inin
y not in xnot y in xเป็นเหตุผลเดียวกับ
นี่คือตัวอย่างบางส่วน:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
สิ่งนี้ยังทำงานร่วมกับสิ่งอันดับเนื่องจากสิ่งอันดับเป็น hashable (อันเป็นผลมาจากความจริงที่ว่าพวกมันยังไม่เปลี่ยนรูป):
(1, 2) in [(3, 4), (1, 2)]
# True
หากวัตถุบน RHS กำหนด__contains__()วิธีการinภายในจะเรียกมันดังที่ระบุไว้ในวรรคสุดท้ายของส่วนการเปรียบเทียบของเอกสาร
... inและnot inได้รับการสนับสนุนตามประเภทที่ iterable หรือใช้
__contains__()วิธีการ ตัวอย่างเช่นคุณสามารถ (แต่ไม่ควร) ทำสิ่งนี้:
[3, 2, 1].__contains__(1)
# True
inลัดวงจรดังนั้นหากองค์ประกอบของคุณอยู่ที่จุดเริ่มต้นของรายการinประเมินได้เร็วขึ้น:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
หากคุณต้องการทำมากกว่าเพียงแค่ตรวจสอบว่ารายการนั้นอยู่ในรายการหรือไม่มีตัวเลือกดังนี้:
list.indexสามารถใช้เพื่อดึงดัชนีของรายการ หากองค์ประกอบนั้นไม่มีอยู่ValueErrorก็จะถูกยกขึ้น
list.count สามารถใช้หากคุณต้องการนับการเกิดขึ้น
ปัญหา XY: คุณเคยคิดsetหรือไม่
ถามตัวเองด้วยคำถามเหล่านี้:
- คุณจำเป็นต้องตรวจสอบว่ารายการนั้นอยู่ในรายการมากกว่าหนึ่งครั้งหรือไม่
- การตรวจสอบนี้เสร็จสิ้นภายในลูปหรือฟังก์ชั่นที่เรียกซ้ำ ๆ กันหรือไม่?
- รายการที่คุณจัดเก็บในรายการของคุณแฮชได้หรือไม่? IOW คุณโทรหา
hashพวกเขาได้ไหม?
หากคุณตอบคำถามเหล่านี้ว่า "ใช่" คุณควรใช้setแทน การinทดสอบการเป็นสมาชิกlistของ s คือความซับซ้อนของเวลา O (n) ซึ่งหมายความว่าหลามจะต้องทำการสแกนเชิงเส้นของรายการของคุณเยี่ยมชมแต่ละองค์ประกอบและเปรียบเทียบกับรายการค้นหา หากคุณทำเช่นนี้ซ้ำ ๆ หรือถ้ารายการมีขนาดใหญ่การดำเนินการนี้จะเกิดค่าใช้จ่าย
setวัตถุในทางกลับกันแฮชค่าสำหรับการตรวจสอบสมาชิกคงที่ การตรวจสอบทำได้โดยใช้in:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
หากคุณโชคร้ายพอที่องค์ประกอบที่คุณกำลังค้นหา / ไม่ค้นหาอยู่ท้ายรายการของคุณหลามจะทำการสแกนรายการจนจบ เรื่องนี้เห็นได้ชัดจากการกำหนดเวลาด้านล่าง:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
เพื่อเป็นการเตือนความจำนี่เป็นตัวเลือกที่เหมาะสมตราบใดที่องค์ประกอบที่คุณจัดเก็บและมองดูนั้นมีแฮช IOW, __hash__พวกเขาทั้งสองจะต้องเป็นชนิดที่ไม่เปลี่ยนรูปหรือวัตถุที่ใช้
3 -1 > 0 and (4-1 , 5) not in []⤇Trueข้อผิดพลาดไม่ใช่หนึ่งในตัวดำเนินการที่สำคัญ