len()-funktion vaativuus¶
Funktio len() palauttaa säiliöolion sisältämien alkioiden lukumäärän.
Vaativuus tyypeittäin¶
| Tyyppi | Aika | Tila | Huomiot |
|---|---|---|---|
list |
O(1) | O(1) | Suora pituusattribuutti |
tuple |
O(1) | O(1) | Muuttumaton, välimuistissa |
dict |
O(1) | O(1) | Ylläpitää kokoa |
set |
O(1) | O(1) | Ylläpitää kokoa |
str |
O(1) | O(1) | Muuttumaton, välimuistissa |
bytes |
O(1) | O(1) | Muuttumaton, välimuistissa |
range |
O(1) | O(1) | Laskettu, ei tallennettu |
deque |
O(1) | O(1) | Ylläpitää kokoa |
defaultdict |
O(1) | O(1) | Peritty sanakirjalta |
OrderedDict |
O(1) | O(1) | Ylläpitää kokoa |
Sisäänrakennetut säiliötyypit¶
Kaikki sisäänrakennetut säiliötyypit pitävät pituutensa muistissa ja palauttavat sen vakioajassa:
# All O(1)
lst = [1, 2, 3, 4, 5]
length = len(lst) # O(1) - stored length
tpl = (1, 2, 3)
length = len(tpl) # O(1) - immutable
dct = {'a': 1, 'b': 2}
length = len(dct) # O(1) - maintains size
s = "hello"
length = len(s) # O(1) - immutable string
Omat oliot¶
Omille luokille len() kutsuu metodia __len__():
class MyContainer:
def __init__(self, items):
self.items = items
def __len__(self):
# Your implementation determines complexity
return len(self.items) # O(1) if efficient
# Usage
obj = MyContainer([1, 2, 3])
length = len(obj) # O(1) - delegates to cached length
# Inefficient implementation
class BadContainer:
def __init__(self, items):
self.items = items
def __len__(self):
# Recomputes from scratch - O(n)!
return sum(1 for _ in self.items)
obj = BadContainer([1, 2, 3])
length = len(obj) # O(n) - iterates through items
Generaattorilausekkeet ja iteraattorit¶
len() EI toimi generaattoreiden eikä iteraattoreiden kanssa:
# Works - list has cached length
lst = [1, 2, 3, 4, 5]
length = len(lst) # O(1)
# Fails - generators don't have length
gen = (x for x in range(5))
# length = len(gen) # TypeError: object of type 'generator' has no len()
# Must consume iterator to count
count = sum(1 for x in gen) # O(n) - must iterate
Yleisiä ratkaisumalleja¶
Säiliön tyhjyyden tarkistaminen¶
# Correct - O(1), doesn't create list
if len(container) > 0:
process(container)
# Also correct - O(1), more Pythonic
if container:
process(container)
# Inefficient - creates a list
if len(list(generator)) > 0: # O(n) - forces evaluation
process(generator)
Koon tarkistaminen¶
def process_list(items):
if len(items) == 0: # O(1)
raise ValueError("Empty list")
if len(items) > 1000: # O(1)
raise ValueError("Too large")
# Process items
for item in items:
pass
Säiliöiden kokojen vertailu¶
# All O(1)
if len(list1) > len(list2):
smaller = list2
larger = list1
else:
smaller = list1
larger = list2
# More efficient than computing actual difference
if len(list1) != len(list2):
print("Different sizes")
Suorituskykyhuomioita¶
Pituusoperaatiot silmukoissa¶
# O(n) - good, length is O(1)
for i in range(len(items)):
process(items[i])
# Also O(n) - length check is O(1) per iteration
count = 0
while count < len(items):
process(items[count])
count += 1
Pituuden esilaskenta¶
items = get_large_list()
# Don't do this - wastes a variable
length = len(items)
for i in range(length): # length already O(1)
process(items[i])
# Instead - directly use len() which is O(1)
for i in range(len(items)):
process(items[i])
Erikoistapaukset¶
Range-oliot¶
# Range length is O(1), not O(n)
r = range(10**1000)
length = len(r) # O(1) - computed from start, stop, step
# This is computed, not stored
# So even huge ranges have O(1) length
Merkkijonojen koodaus¶
# All string types have O(1) length
s = "hello"
length = len(s) # O(1) - character count
b = b"hello"
length = len(b) # O(1) - byte count
# Note: len(str) counts characters, not bytes
s = "café"
print(len(s)) # 4 - four characters
print(len(s.encode('utf-8'))) # 5 - five bytes
Versiohuomiot¶
- Python 2.x:
len()toimii sisäänrakennetuilla tyypeillä ja omalla__len__-metodilla - Python 3.x: Sama käyttäytyminen, johdonmukaisemmin
- Kaikki versiot: O(1) sisäänrakennetuille säiliöille (ne pitävät pituuden muistissa)
Liittyvät funktiot¶
- all() - Tarkistaa, ovatko kaikki alkiot tosia
- any() - Tarkistaa, onko jokin alkio tosi
- max() - Etsii suurimman arvon
- min() - Etsii pienimmän arvon
- sum() - Laskee alkioiden summan
Parhaat käytännöt¶
✅ Tee näin:
- Käytä
len()-funktiota säiliön tyhjyyden tarkistamiseen (se on O(1)) - Käytä muotoa
if container:totuusarvotarkistuksiin - Tallenna pituus muuttujaan vain, jos sitä käytetään toistuvasti tiukoissa silmukoissa
❌ Vältä:
len(list(generator))generaattorin alkioiden laskemiseen (O(n))- Pituuden uudelleenlaskentaa
__len__-metodissa (se tulisi pitää muistissa) - Oletusta, että generaattoreilla on pituus (niillä ei ole)