Czy istnieje proste wyrażenie generatora, które może dać nieskończone elementy?
To jest kwestia czysto teoretyczna. Nie ma tu potrzeby "praktycznej" odpowiedzi :)
Na przykład łatwo jest utworzyć skończony generator:
my_gen = (0 for i in xrange(42))
Jednak aby stworzyć nieskończoną, muszę „zanieczyścić” moją przestrzeń nazw fałszywą funkcją:
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
Robienie rzeczy w osobnym pliku i import
późniejsze nie liczą się.
Wiem też, że itertools.repeat
to właśnie robi. Ciekawi mnie, czy bez tego istnieje jednoliniowe rozwiązanie.
python
iterator
generator
infinite-loop
hugomg
źródło
źródło
my_gen
a następnie zróbmy_gen = my_gen()
.del _my_gen
jeśli nie chcesz mylić tych dwóchOdpowiedzi:
iter
= wywoływalne zeroargumentowe + wartość wartownikaint()
zawsze wraca0
Dlatego
iter(int, 1)
jest nieskończoną iteratorem. Oczywiście istnieje ogromna liczba odmian tego konkretnego tematu (szczególnie po dodaniulambda
do miksu). Jednym z wariantów szczególnej uwagi jest toiter(f, object())
, że użycie świeżo utworzonego obiektu jako wartości wartowniczej prawie gwarantuje nieskończony iterator, niezależnie od wywołania używanego jako pierwszy argument.źródło
iter
właściwości, oint
których wielokrotnie zapominamy.itertools.count
:count = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
iter
-function jest wywoływana z dwoma argumentami, to zachowuje się trochę inaczej niż zwykle:iter(callable, sentinel) -> iterator
. Argument 1callable
jest wywoływany dla każdej iteracji iteratora, dopóki nie zwróci wartościsentinel
. Jednak, jakint()
zawsze wrócimy0
, możemy dzwonić naint()
zawsze i nigdy nie osiągnąć 1. To w efekcie stworzy nieskończoną listę0
'sitertools
zapewnia trzy nieskończone generatory:count(start=0, step=1)
: 0, 1, 2, 3, 4, ...cycle(p)
: p [0], p [1], ..., p [-1], p [0], ...repeat(x, times=∞)
: x, x, x, x, ...Nie znam innych w standardowej bibliotece.
Ponieważ poprosiłeś o jedną linijkę:
źródło
∞
symbolu dla tego, kto się zastanawiał - pominięcie argumentu powoduje, że powtarzanie trwa na zawszeiter(int, 1)
zaklęcie. Szkoda,itertools
że nie maendlessly()
metody, której jedynym celem jest zrobienie tego;itertools.count()
też nie jest aż tak czytelny.możesz iterować po wywołanym zwracaniu stałej zawsze innej niż wartownik iter ()
źródło
iter
(tutaj z dodatkowym wartownikiem) i składnięlambda
(tutaj bez żadnych przekazanych parametrów, po prostureturn 0
), jedyne miejsce do nienawiści jest to enigmatyczneg1
.Twój system operacyjny może udostępniać coś, co może być używane jako nieskończony generator. Np. Na Linuksie
oczywiście nie jest to tak wydajne jak
źródło
\n
że od czasu do czasu pojawiają się znaki ... Podstępne! :)Żaden, który nie używa wewnętrznie innego nieskończonego iteratora zdefiniowanego jako klasa / funkcja / generator (nie -wyrażenie, funkcja z
yield
). Wyrażenie generatora zawsze pobiera z innego iterowalnego i nie robi nic poza filtrowaniem i mapowaniem jego elementów. Nie możesz przejść od elementów skończonych do nieskończonych, mając tylkomap
ifilter
, czego potrzebujeszwhile
(lub cośfor
, co się nie kończy, co jest dokładnie tym, czego nie możemy mieć przy użyciu tylkofor
i skończonych iteratorów).Ciekawostka: PEP 3142 jest pozornie podobny, ale po bliższym przyjrzeniu się wydaje się, że nadal wymaga
for
klauzuli (więc nie(0 while True)
dla ciebie), tj. Zapewnia tylko skrót doitertools.takewhile
.źródło
from itertools import repeat, count, cycle
prawdopodobnie liczy się jako „łatwo dostępny” dla większości ludzi.iter
. Nieskończone iteratory są faktycznie dostępne jako wbudowane - zobacz moją odpowiedź :)Dość brzydki i szalony (jednak bardzo zabawny), ale możesz zbudować swój własny iterator z wyrażenia, używając kilku sztuczek (bez "zanieczyszczania" przestrzeni nazw zgodnie z wymaganiami):
źródło
Może przydałbyś się na przykład dekoratorów takich jak ten:
Użycie (1):
Zastosowanie (2)
Myślę, że można by jeszcze bardziej ulepszyć pozbycie się tych brzydkich
()
. Jednak zależy to od złożoności sekwencji, którą chcesz móc utworzyć. Mówiąc ogólnie, jeśli twoja sekwencja może być wyrażona za pomocą funkcji, wówczas cała złożoność i cukier składniowy generatorów może być ukryta wewnątrz dekoratora lub funkcji podobnej do dekoratora.źródło
def
i zamknięciem? ;)(2^x)
, możesz mieć(x)
. Jeśli trochęseq
i wciskając kod bezpośrednio dowrap