Len () fonksiyonunun maliyeti


Yanıtlar:


341

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) setve bu şekilde diğerlerinin array.array.


17
Yararlı cevap için teşekkürler! Bunun böyle olmadığı yerel türler var mı?
— mvanveen


84

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


3
Bunun en uygun cevap olduğunu düşünüyorum, çünkü bu uygulama ayrıntılarını anlıyor.
— AK

neden lengthsözlükte gösterilmiyor dir(list)?
— ViFI

aradığım şey buydu
— Visakh Vijayan

@ViFI Çünkü bu sadece bir örnek. Gösterilen list.lenghtdeğişken Python değil C olarak uygulanır.
— Kowalski

73

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: -sBayrak kullanıldığında ve timeitilk dizeye iki dize geçirildiğinde yalnızca bir kez yürütülür ve zamanlanmaz.

Liste:

$ 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

Kayıt düzeni:

$ 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

Dize:

$ 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

Sözlük (sözlük anlama 2.7 ve üstü sürümlerde mevcuttur):

$ 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

Dizi:

$ 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 üstü kavrama 2.7 ve üstü sürümlerde mevcuttur):

$ 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
Zaten bildiğimizi göstermesine rağmen bu bir kriter kadar iyi değil. Bunun nedeni (10) ve (1000000) aralığının O (1) olması gerekmemesidir.
— Bilinmiyor

3
Bu açık ara en iyi cevap. Birisinin sürekli zamanı fark etmemesi durumunda bir sonuç eklemelisiniz.
— santiagobasulto

4
Yorum için teşekkürler. O (1) karmaşıklığı hakkında bir not ekledim len()ve ayrıca -sbayrağı uygun şekilde kullanmak için ölçümleri sabitledim .
— mechanical_meat

Uzunluğun bir değişkene kaydedilmesinin önemli miktarda hesaplama süresinden tasarruf edebileceğini unutmamak önemlidir: 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
— Radostin Stoyanov

16

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.


3

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.


Ancak __len__bir işlevdir, bir listenin uzunluğunu temsil eden bir değişken değildir.
— Kowalski

@Kowalski yes len bir işlevdir ama tek yaptığı şey
— self.length

Fakat yayınınız bu konuda hiçbir şey söylemiyor. Ayrıca bu 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ı.
— Kowalski
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.