ค่าใช้จ่ายของ len () ฟังก์ชั่น


คำตอบ:


341

มันO (1) (เวลาคงไม่ได้ขึ้นอยู่กับความยาวจริงขององค์ประกอบ - เร็วมาก) ในทุกประเภทที่คุณได้กล่าวถึงบวกsetและอื่น ๆ array.arrayเช่น


17
ขอบคุณสำหรับคำตอบที่เป็นประโยชน์! มีชนพื้นเมืองประเภทใดที่ไม่ใช่กรณีนี้หรือไม่?
mvanveen


84

วัตถุเหล่านั้นติดตามความยาวของตัวเอง เวลาในการแยกความยาวนั้นมีขนาดเล็ก (O (1) ในรูปแบบ big-O) และส่วนใหญ่ประกอบด้วย [คำอธิบายคร่าวๆเขียนใน Python ข้อตกลงไม่ใช่คำศัพท์ C]: ค้นหา "len" ในพจนานุกรมและส่งไปยัง ฟังก์ชั่น built_in len ซึ่งจะค้นหา__len__วิธีการของวัตถุและเรียกว่า ... ทั้งหมดที่ต้องทำคือreturn self.length


3
ฉันคิดว่านี่เป็นคำตอบที่เหมาะสมที่สุดเพราะนี่จะให้รายละเอียดเกี่ยวกับการใช้งาน
AK

ทำไมถึงไม่lengthปรากฏในพจนานุกรมโดยdir(list)?
ViFI

นี่คือสิ่งที่ฉันกำลังมองหา
Visakh Vijayan

@ViFI เพราะมันเป็นเพียงตัวอย่าง list.lenghtตัวแปรที่แสดงนั้นถูกนำไปใช้ใน C ไม่ใช่ Python
สกี้

73

การวัดด้านล่างแสดงหลักฐานว่า len()เป็น O (1) สำหรับโครงสร้างข้อมูลที่ใช้บ่อย

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

รายการ:

$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop

$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop

tuple:

$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop

$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop

สตริง:

$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop

$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop

พจนานุกรม (ความเข้าใจในพจนานุกรมมีให้ใน 2.7+):

$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop

$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop

อาร์เรย์:

$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop

$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop

Set (set-comprehension มีอยู่ใน 2.7+):

$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop

$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop

deque:

$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop

$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop

1
มันไม่ได้เป็นมาตรฐานที่ดีแม้ว่ามันจะแสดงสิ่งที่เรารู้อยู่แล้วก็ตาม นี่เป็นเพราะช่วง (10) และช่วง (1000000) ไม่ควรเป็น O (1)
ไม่รู้จัก

3
นี่คือคำตอบที่ดีที่สุด คุณควรเพิ่มข้อสรุปในกรณีที่บางคนไม่ตระหนักถึงเวลาที่แน่นอน
santiagobasulto

4
ขอบคุณสำหรับความคิดเห็น ฉันได้เพิ่มข้อความเกี่ยวกับความซับซ้อนของ O (1) len()และแก้ไขการวัดเพื่อใช้-sธงอย่างถูกต้อง
mechanical_meat

สิ่งสำคัญที่ควรทราบคือการบันทึกความยาวลงในตัวแปรสามารถประหยัดเวลาการคำนวณได้อย่างมาก: python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)"223 nsec ต่อหนึ่งวงpython -m timeit -s "l = range(100);" "len(l)"66.2 nsec ต่อหนึ่งวง
Radostin Stoyanov

16

len เป็น O (1) เนื่องจากใน RAM รายการจะถูกจัดเก็บเป็นตาราง (ชุดของที่อยู่ต่อเนื่อง) หากต้องการทราบว่าเมื่อใดที่ตารางหยุดคอมพิวเตอร์จำเป็นต้องมีสองสิ่ง: ความยาวและจุดเริ่มต้น นั่นคือเหตุผลที่ len () คือ O (1) คอมพิวเตอร์เก็บค่าไว้ดังนั้นมันจึงจำเป็นต้องค้นหา


3

ฉันคิดถึง len () ใน Python ขึ้นอยู่กับขนาดของรายการดังนั้นฉันมักจะเก็บความยาวในตัวแปรถ้าฉันใช้หลายครั้ง แต่วันนี้ในขณะที่การดีบั๊กผมสังเกตว่าแอตทริบิวต์ __len__ ในรายการวัตถุดังนั้น len () จะต้องดึงมันมาซึ่งทำให้ความซับซ้อน O (1) ดังนั้นฉันจึง googled ถ้ามีคนถามแล้วและเจอโพสต์นี้


แต่__len__เป็น funtion ไม่ใช่ตัวแปรที่แสดงความยาวของรายการ
โควาลสกี้

@Kowalski ใช่lenเป็นฟังก์ชั่น แต่สิ่งที่มันทำคือมันคืนค่าตัวเองความยาว
AYUSH SENAPATI

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