• Programowanie
  • Python len() bez tajemnic - znaki, listy i generatory

Python len() bez tajemnic - znaki, listy i generatory

Tymoteusz Maciejewski • 31 października 2026
Fragment kodu Pythona pokazujący błędy funkcji len() dla różnych typów danych.

Masz listę produktów, tekst z formularza albo słownik z danymi i chcesz szybko sprawdzić, ile zawiera elementów. Najczęściej wywołujesz len(obiekt), które zwraca liczbę elementów, choć wynik zależy od tego, co Python uznaje za element i jaki typ danych przekazujesz.

[search_image]funkcja len w Pythonie przykład kodu lista napis słownik[/search_image]

Jedno wywołanie, kilka różnych znaczeń długości

  • len() zwraca liczbę elementów sekwencji albo kolekcji.
  • Dla słownika otrzymasz liczbę kluczy, a dla tekstu liczbę znaków rozumianych jako punkty kodowe Unicode.
  • Generator nie ma ustalonej długości, więc len(generator) kończy się błędem.
  • Do sprawdzania, czy kolekcja jest pusta, czytelniejszy zapis to if not kolekcja.
  • Własna klasa może współpracować z len(), jeśli zdefiniujesz w niej metodę __len__().

len() zwraca liczbę elementów, a nie rozmiar obiektu

Najprostszy przykład wygląda tak:

imiona = ["Ola", "Jan", "Marek"]
liczba_imion = len(imiona)

print(liczba_imion)  # 3

Funkcja nie analizuje zawartości każdego elementu. Dla listy liczy pozycje, dla krotki elementy, dla zbioru wartości, a dla słownika klucze. Oficjalna dokumentacja wbudowanej funkcji len wymienia między innymi napisy, bajty, krotki, listy, zakresy, słowniki i zbiory jako obiekty obsługujące takie wywołanie.

Obiekt Kod Wynik Co jest liczone
Lista len([10, 20, 30]) 3 Elementy listy
Krotka len(("a", "b")) 2 Elementy krotki
Słownik len({"id": 7, "aktywny": True}) 2 Klucze
Zbiór len({2, 2, 4, 6}) 3 Unikalne elementy
Zakres len(range(5, 15)) 10 Wartości generowane przez zakres

Najczęstsza pomyłka pojawia się przy strukturach zagnieżdżonych. Dla danych poniżej wynik wynosi 2, ponieważ lista zawiera dwa wiersze, chociaż w środku znajduje się łącznie pięć liczb:

wiersze = [[1, 2], [3, 4, 5]]

print(len(wiersze))        # 2
print(len(wiersze[0]))     # 2
print(len(wiersze[1]))     # 3

Jeżeli potrzebujesz liczby wszystkich wartości wewnątrz wierszy, pytanie brzmi już inaczej. Wtedy trzeba przejść po zagnieżdżonych kolekcjach, bo samo len(wiersze) opisuje wyłącznie zewnętrzną listę.

Przy tekście len() liczy punkty kodowe, nie bajty UTF-8

Tekst potrafi wyglądać jak jeden znak, a w pamięci lub podczas wysyłania przez sieć zajmować kilka bajtów. W Pythonie str jest sekwencją punktów kodowych Unicode, natomiast bytes przechowuje wartości bajtowe. To dwa różne poziomy danych.

tekst = "ą"
dane = tekst.encode("utf-8")

print(len(tekst))  # 1
print(len(dane))   # 2

Wynik 1 oznacza jeden punkt kodowy w obiekcie tekstowym. Wynik 2 oznacza dwa bajty po zakodowaniu znaku ą w UTF-8. Z tego powodu len(napis) nie odpowiada automatycznie liczbie bajtów pliku, żądania HTTP ani pola w bazie danych. Szczegóły tej różnicy opisuje dokumentacja typów tekstowych Pythona, a praktyczne rozróżnienie znajdziesz także w materiale o kodowaniu UTF-8.

Przy ograniczeniu formularza trzeba więc najpierw ustalić, czego dotyczy limit. Dla limitu 50 znaków użyj len(tekst). Dla limitu 50 bajtów sprawdź długość wyniku kodowania:

tekst = "Zażółć gęślą jaźń"

liczba_znakow = len(tekst)
liczba_bajtow = len(tekst.encode("utf-8"))

print(liczba_znakow)
print(liczba_bajtow)

Ta różnica potrafi zmienić działanie walidacji. Tekst może przejść test liczby znaków, a jednocześnie przekroczyć limit narzucony przez protokół albo usługę, która liczy rozmiar danych po zakodowaniu.

Do pustej kolekcji użyj warunku, a do liczenia elementów funkcji

Czasem nie potrzebujesz liczby. Chcesz wyłącznie wiedzieć, czy lista zawiera dane. W takim przypadku ten zapis:

zadania = []

if not zadania:
    print("Brak zadań")

jest czytelniejszy niż if len(zadania) == 0. Pusta lista, krotka, napis, słownik i zbiór są traktowane jako fałsz logiczny. PEP 8 zaleca korzystanie z tej właściwości sekwencji zamiast sprawdzania długości w warunku.

Sytuacja Prawdopodobna przyczyna lub skutek Co zrobić
Chcesz wyświetlić liczbę wszystkich rekordów Potrzebujesz długości kolekcji Użyj len(rekordy)
Chcesz sprawdzić, czy lista jest pusta Nie potrzebujesz konkretnej liczby Użyj if not lista
Chcesz policzyć elementy spełniające warunek len() policzyłoby także elementy niespełniające warunku Użyj sum(warunek for element in dane)
Przekazujesz generator Generator nie przechowuje gotowej długości Przetwórz go iteracyjnie albo utwórz listę, jeśli potrzebujesz liczby
Sprawdzasz argument, który może być None if not argument potraktuje jako pustą także wartość 0 lub pusty tekst Użyj if argument is None, gdy sprawdzasz brak wartości

Generator dobrze pokazuje granicę działania tej funkcji:

liczby = (liczba for liczba in range(5))

print(len(liczby))  # TypeError

Generator produkuje wartości dopiero podczas iteracji, więc nie ma ustalonego rozmiaru, który można odczytać bez uruchamiania całego procesu. Konwersja do listy zadziała, lecz zużyje pamięć i jednocześnie pobierze wszystkie elementy:

liczby = (liczba for liczba in range(5))
lista_liczb = list(liczby)

print(len(lista_liczb))  # 5

Reguła jest prosta. Jeśli potrzebujesz liczby, użyj len(); jeśli potrzebujesz tylko odpowiedzi tak lub nie, sprawdź prawdziwość obiektu; jeśli dane powstają strumieniowo, nie zakładaj, że mają długość.

Własna klasa może działać z len() dzięki __len__()

Ta funkcja nie jest zarezerwowana dla list i słowników. Własny obiekt również może udostępniać długość, jeśli klasa definiuje metodę __len__():

class Koszyk:
    def __init__(self, produkty):
        self.produkty = produkty

    def __len__(self):
        return len(self.produkty)


koszyk = Koszyk(["kawa", "herbata", "cukier"])

print(len(koszyk))  # 3

Metody z podwójnym podkreśleniem, nazywane metodami specjalnymi, opisują sposób współpracy obiektu z językiem. Według modelu danych Pythona __len__() powinna zwracać nieujemną liczbę całkowitą. Gdy wynik wynosi zero, obiekt może być także uznany za fałsz w warunku.

Własną klasę można oznaczyć jako obiekt o znanym rozmiarze także przy pomocy collections.abc.Sized. Ten abstrakcyjny interfejs opisuje obiekty, które zapewniają metodę __len__(), więc pozwala sprawdzić, czy dana wartość obsługuje długość bez zgadywania jej konkretnego typu.

from collections.abc import Sized

def pokaz_rozmiar(obiekt):
    if isinstance(obiekt, Sized):
        return len(obiekt)
    return None

Przy projektowaniu własnej klasy trzeba najpierw ustalić, co ma być liczone. W koszyku może chodzić o liczbę pozycji produktowych, a w systemie rezerwacji o liczbę osób. Sama metoda będzie poprawna technicznie, lecz jej znaczenie musi być jasne dla osoby korzystającej z obiektu. Wynik możesz potem wyświetlić przez funkcję print w Pythonie, ale prezentacja nie zmienia tego, co faktycznie zwraca len().

W kilku przypadkach długość wymaga dodatkowej ostrożności

Najbardziej zaskakujący przypadek dotyczy ogromnego zakresu:

zakres = range(2 ** 100)
print(len(zakres))

W CPython takie wywołanie może zakończyć się błędem OverflowError, ponieważ długość przekracza limit reprezentowany przez sys.maxsize. Sam obiekt range nie przechowuje wszystkich wartości w pamięci, lecz funkcja nadal musi zwrócić długość w obsługiwanym typie liczbowym.

Inna pułapka pojawia się przy metodzie __length_hint__(). Nie zastępuje ona __len__(). Jest tylko podpowiedzią dla operacji, które mogą wcześniej zarezerwować miejsce na wynik. Oficjalna dokumentacja modelu danych zaznacza, że podpowiedź może być większa albo mniejsza od rzeczywistej długości i nie jest wymagana do poprawnego działania programu.

from operator import length_hint

iterator = iter([10, 20, 30])
print(length_hint(iterator))

Nie używaj length_hint() do walidowania danych biznesowych, limitów użytkownika ani warunków bezpieczeństwa. Do takich decyzji potrzebujesz rzeczywistej liczby elementów albo jawnego przejścia po danych.

Jeszcze jedna granica dotyczy słowników. len(dane) odpowiada liczbie kluczy, a nie liczbie wszystkich wartości zagnieżdżonych w strukturze. Dla obiektu poniżej wynik wynosi 2, mimo że wewnątrz znajdują się trzy wartości liczbowe:

dane = {
    "punkty": [10, 20],
    "bonus": 5
}

print(len(dane))  # 2

Gdy decyzja zależy od zawartości, a nie od liczby kluczy, trzeba wybrać właściwe wyrażenie, na przykład len(dane["punkty"]) albo osobne zliczanie wartości. To drobne rozróżnienie często decyduje o tym, czy raport pokaże liczbę rekordów, pól czy pojedynczych danych.

Najlepszy skrót myślowy do codziennej pracy z len()

Możesz zapamiętać cztery pytania, które szybko prowadzą do poprawnego rozwiązania:

  • Co jest elementem? W słowniku klucz, w napisie punkt kodowy, w liście pozycja.
  • Czy potrzebujesz liczby? Jeśli nie, użyj testu logicznego zamiast len().
  • Czy obiekt ma gotową długość? Generator jej nie udostępnia, a własna klasa może wymagać __len__().
  • Czy chodzi o znaki czy bajty? Przy transmisji i limitach technicznych sprawdź także wynik .encode("utf-8").

Uważam, że największą pułapką nie jest sama składnia len(obiekt), tylko bezrefleksyjne założenie, że „długość” zawsze oznacza to samo. Gdy najpierw nazwiesz jednostkę, którą chcesz policzyć, wybór między len(), warunkiem logicznym, iteracją i kodowaniem tekstu staje się dużo prostszy.

W praktyce funkcja pozostaje bardzo krótka, lecz opiera się na protokole obiektu. To właśnie dlatego ten sam zapis działa dla listy, słownika, własnej klasy i wielu innych kolekcji, a dla generatora albo liczby kończy się innym rezultatem.

Oceń artykuł

Ocena: 4.25 Liczba głosów: 4

Tagi

python
len()
unicode
generatory
kolekcje
Autor Tymoteusz Maciejewski
Tymoteusz Maciejewski
Moje dni wypełnia zgłębianie kodu i analiza nowych technologii, zawsze z myślą o tym, jak najlepiej przekazać tę wiedzę dalej. Nazywam się Tymoteusz Maciejewski i od 12 lat aktywnie działam w świecie programowania, technologii i kariery w IT. Interesuje mnie nie tylko samo tworzenie oprogramowania, ale także proces, który prowadzi do zrozumienia złożonych zagadnień i uporządkowania ich w przystępny sposób. Na lukasz-zielinski.pl staram się dzielić się tym, co sam odkrywam, sprawdzając informacje u podstaw i dbając o to, by treści były aktualne i zrozumiałe dla każdego, kto chce rozwijać się w tej dynamicznej branży.

Udostępnij artykuł

Napisz komentarz