Yanıtlar:
It adlı Ç (1) Eğer açıkladığım tüm türüne artı - (çok hızlı sabit zaman, elemanın gerçek uzunluğunun bağlı değil) set
ve bu şekilde diğerlerinin array.array
.
Bu veri türlerinde len () çağrısı , Python dilinin en yaygın uygulaması olan CPython'da O (1) 'dir . İşte CPython'daki birçok farklı fonksiyonun algoritmik karmaşıklığını sağlayan bir tabloya bağlantı:
Tüm bu nesneler kendi uzunluklarını takip eder. Uzunluğu ayıklama süresi küçüktür (büyük O gösterimlerinde O (1)) ve çoğunlukla [kaba terimler, C terimleriyle değil, Python terimleriyle yazılmıştır]: sözlükte "len" kelimesini arayın ve nesnenin __len__
yöntemini arayacak ve bunu çağıracak built_in len fonksiyonu ... tek yapması gerekenreturn self.length
length
sözlükte gösterilmiyor dir(list)
?
list.lenght
değişken Python değil C olarak uygulanır.
Aşağıdaki ölçümler len()
, sıkça kullanılan veri yapıları için O (1) kanıtıdır .
Şununla ilgili bir not timeit
: -s
Bayrak kullanıldığında ve timeit
ilk dizeye iki dize geçirildiğinde yalnızca bir kez yürütülür ve zamanlanmaz.
$ 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()
ve ayrıca -s
bayrağı uygun şekilde kullanmak için ölçümleri sabitledim .
python -m timeit -s "l = range(10000);" "len(l); len(l); len(l)"
döngü başına 223 nsec döngü başına python -m timeit -s "l = range(100);" "len(l)"
66,2 nsec
len bir O (1) 'dir, çünkü RAM'inizde listeler tablo olarak saklanır (bitişik adresler dizisi). Masanın ne zaman durduğunu bilmek için bilgisayarın iki şeye ihtiyacı vardır: uzunluk ve başlangıç noktası. Bu yüzden len () bir O (1), bilgisayar değeri saklar, bu yüzden sadece araması gerekir.
Python len () listenin büyüklüğüne bağlıdır düşünüyorum, bu yüzden her zaman birden çok kez kullanırsanız bir değişken uzunluğu saklamak. Ama bugün hata ayıklama sırasında, liste nesnesindeki __len__ özniteliğini fark ettim, bu yüzden len () sadece onu almalı, bu da O (1) karmaşıklığını yapar. Bu yüzden, birisi daha önce sordu ve bu gönderiye rastladıysa googled.
__len__
bir işlevdir, bir listenin uzunluğunu temsil eden bir değişken değildir.
list.__len__
fonksiyonun sabit zamanda çalıştığını nasıl anlarsınız ? Sadece bir fonksiyon olduğu için değil. Çünkü böyle uyguladı.