Câu trả lời:
Đó là O (1) (thời gian không đổi, không phụ thuộc vào độ dài thực tế của phần tử - rất nhanh) trên mọi loại bạn đã đề cập, cộng với các set
loại khác như array.array
.
Gọi len () trên các loại dữ liệu đó là O (1) trong CPython , cách triển khai phổ biến nhất của ngôn ngữ Python. Đây là một liên kết đến một bảng cung cấp độ phức tạp thuật toán của nhiều hàm khác nhau trong CPython:
Tất cả những đối tượng theo dõi chiều dài của riêng họ. Thời gian để trích xuất độ dài là nhỏ (O (1) trong ký hiệu big-O) và chủ yếu bao gồm [mô tả thô, được viết bằng thuật ngữ Python, không phải thuật ngữ C]: tra cứu "len" trong từ điển và gửi nó đến Hàm build_in len sẽ tìm kiếm __len__
phương thức của đối tượng và gọi rằng ... tất cả những gì nó phải làm làreturn self.length
length
xuất hiện trong từ điển dir(list)
?
list.lenght
được thực hiện trong C, không phải Python.
Các phép đo dưới đây cung cấp bằng chứng len()
là O (1) cho các cấu trúc dữ liệu được sử dụng.
Một lưu ý liên quan đến timeit
: Khi -s
cờ được sử dụng và hai chuỗi được chuyển đếntimeit
chuỗi đầu tiên chỉ được thực hiện một lần và không được tính thời gian.
$ 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
$ 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
$ 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
$ 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
$ 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
len()
và cũng đã sửa các phép đo để sử dụng -s
cờ đúng cách .
python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)"
223 nsec mỗi vòng python -m timeit -s "l = range(100);" "len(l)"
66,2 nsec mỗi vòng
len là một O (1) vì trong RAM của bạn, các danh sách được lưu dưới dạng bảng (chuỗi các địa chỉ liền kề). Để biết khi nào bảng dừng máy tính cần hai thứ: chiều dài và điểm bắt đầu. Đó là lý do tại sao len () là O (1), máy tính lưu trữ giá trị, vì vậy nó chỉ cần tra cứu nó.
Tôi đã nghĩ về len () trong Python phụ thuộc vào kích thước của danh sách, vì vậy tôi luôn lưu trữ độ dài trong một biến nếu tôi sử dụng nhiều lần. Nhưng hôm nay trong khi gỡ lỗi, tôi nhận thấy thuộc tính __len__ trong đối tượng danh sách, vì vậy len () phải chỉ tìm nạp nó, điều này làm cho độ phức tạp O (1). Vì vậy, tôi chỉ loay hoay nếu ai đó đã hỏi nó và xem qua bài đăng này.
__len__
là một chức năng, không phải là một biến đại diện cho chiều dài của danh sách.
list.__len__
chức năng chạy trong thời gian liên tục? Nó không, nhưng không chỉ vì nó là một chức năng. Bởi vì nó thực hiện như vậy.