ฉันจะตรวจสอบว่ามีสิ่งใด (ไม่) ในรายการใน Python ได้อย่างไร
วิธีที่ถูกที่สุดและอ่านง่ายที่สุดคือการใช้in
โอเปอเรเตอร์ (หรือในกรณีเฉพาะของคุณnot in
) ตามที่ระบุไว้ในเอกสาร
ผู้ประกอบการin
และnot in
ทดสอบการเป็นสมาชิก x in s
ประเมิน
True
ว่าหากx
เป็นสมาชิกของs
และFalse
อื่น ๆ ผลตอบแทนของการปฏิเสธx not in s
x in s
นอกจากนี้
ผู้ประกอบการที่มีการกำหนดให้มีมูลค่าที่แท้จริงผกผันของnot in
in
y not in x
not 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
ข้อผิดพลาดไม่ใช่หนึ่งในตัวดำเนินการที่สำคัญ