Wpis z mikrobloga

@powiemjedno: bo generator jest po to, żebyś dostał kolejny element tylko wtedy gdy go potrzebujesz i nie zajmował niepotrzebnie pamięci.

A len musi zliczyć wszystkie elementy, których ilość jest nieznana w generatorze, bo generator będzie wypluwał coś na żądanie dopóki coś jest i teoretycznie może się nigdy nie skończyć.
  • Odpowiedz
@powiemjedno:

Jeśli generator implementuje funkcję __len__ to zadziała, np. range(10).__len__(). Ale to jest raczej wyjątek.

Jeśli chcesz dowiedzieć się, ile jest elementów w generatorze to możesz je policzyć, np. sum(1 for x in generator) (o ile jest ich skończona liczba). Po tej operacji generator będzie pusty.
  • Odpowiedz
@morsik: To by miało sens, gdyby wszystkie z podanych przeze mnie funkcji tak działały. Ale tylko len(...) jest tak "zabezpieczona", bo np. sorted(...) akceptuje generator i nie boi się, że mógłby być nieskończony.
  • Odpowiedz
@powiemjedno: odwrotnie: to nie len() jest zabezpieczone, tylko sorted() jest funkcją na wyższym poziomie abstrakcji.

- sorted() pobiera element iterowalny. Generator takim jest.
https://docs.python.org/3/library/functions.html#sorted

- len() tak naprawdę nie istnieje (a raczej normalnie nic nie umie zrobić - istnieje tylko nazwa wbudowana). To jest ładna nazwa dla wewnętrznej metody __len__() zaimplementowanej wewnątrz danej klasy. A klasa generatora nie umie zwracać nic pod __len__(). Mógłbyś sobie napisać swoją klasę która umiałaby
  • Odpowiedz
@morsik: Dzięki za link. Na SO też w komentarzach wskazują na tę samą niekonsekwencję. Skoro można zsumować wszystkie elementy generatora, to czemu nie można ich policzyć. Tłumaczenie, że len nie działa na generator, bo nie jest zaimplementowana, jest takim trochę argumentem typu "obiadu nie ma, bo nikt go nie ugotował". Mnie chodziło raczej o decyzję deweloperów pythona, dlaczego tego nie zrobili.
  • Odpowiedz
Skoro można zsumować wszystkie elementy generatora, to czemu nie można ich policzyć.


@powiemjedno: len nie liczy ilości elementów z listy, ale w zasadzie to wczytuje z pamięci jej długość zapisaną w strukturze (przynajmniej w cPythonie)
  • Odpowiedz