jak wybrać tylko jeden element z generatora (w Pythonie)?
Mam funkcję generatora jak poniżej:
def myfunct():
...
yield result
Zwyczajowym sposobem wywołania tej funkcji jest:
for r in myfunct():
dostuff(r)
Moje pytanie, czy jest sposób, aby dostać tylko jeden element z generatora, kiedy tylko chcę? Na przykład, chciałbym zrobić coś w stylu:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
5 answers
Tworzenie generatora za pomocą
g = myfunct()
Za każdym razem, gdy chcesz przedmiot, użyj
next(g)
(lub g.next()
w Pythonie 2.5 lub poniżej).
Jeśli generator wyjdzie, podniesie się StopIteration
. W razie potrzeby możesz przechwycić ten wyjątek lub użyć argumentu default
do next()
:
next(g, default_value)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 09:31:32
Do wybrania tylko jednego elementu generatora użyj break
w instrukcji for
lub list(itertools.islice(gen, 1))
Według twojego przykładu (litteralnie) możesz zrobić tak:
while True:
...
if something:
for my_element in myfunct():
dostuff(my_element)
break
else:
do_generator_empty()
Jeśli chcesz " uzyskać tylko jeden element z generatora [once generated] kiedy tylko chcę" (przypuszczam, że 50% to pierwotna intencja i najczęstsza intencja), to:
gen = myfunct()
while True:
...
if something:
for my_element in gen:
dostuff(my_element)
break
else:
do_generator_empty()
W ten sposób można uniknąć jawnego użycia generator.next()
, a obsługa końca wejścia nie wymaga (cryptic) StopIteration
obsługa wyjątków lub dodatkowe porównywanie wartości domyślnych.
Sekcja else:
z for
jest potrzebna tylko, jeśli chcesz zrobić coś specjalnego w przypadku generatora końca.
Uwaga na next()
/ .next()
:
W Python3 metoda .next()
została przemianowana na .__next__()
nie bez powodu: jest uważana za niskopoziomową (PEP 3114). Przed Pythonem 2.6 wbudowana funkcja next()
nie istniała. I nawet dyskutowano o przeniesieniu next()
do operator
modułu (co byłoby mądre), ze względu na rzadką potrzebę i wątpliwą inflację nazw.
Używanie next()
bez domyślnego ustawienia jest nadal bardzo mało praktyczną praktyką-rzucanie tajemnicą StopIteration
jak piorun znikąd w normalnym kodzie aplikacji otwarcie. I używanie {[9] } z domyślnym sentinel - który najlepiej powinien być jedyną opcją dla next()
bezpośrednio w builtins
- jest ograniczone i często daje powód do dziwnej nie pythonicznej logiki / czytelności.
Podsumowując: użycie next() powinno być bardzo rzadkie - jak użycie funkcje modułu {[15] }. Za pomocą for x in iterator
, islice
, list(iterator)
i inne funkcje, które bezproblemowo akceptują Iteratory, są naturalnym sposobem korzystania z iteratorów na poziomie aplikacji - i to całkiem zawsze możliwe. next()
jest niskopoziomowym, dodatkowym pojęciem, nieoczywistym - jak pokazuje kwestia tego wątku. Podczas gdy np. użycie break
w {[3] } jest konwencjonalne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-18 17:23:43
Nie wierzę, że jest wygodny sposób na pobranie dowolnej wartości z generatora. Generator dostarczy metodę next (), która sama się przemierzy, ale pełna sekwencja nie jest wytwarzana natychmiast, aby zapisać pamięć. To jest funkcjonalna różnica między generatorem a listą.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-19 21:59:31
generator = myfunct()
while True:
my_element = generator.next()
Upewnij się, że wyłapujesz wyjątek wyrzucony po wzięciu ostatniego elementu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-19 22:01:17
Wierzę, że jedynym sposobem jest uzyskanie listy z iteratora, a następnie uzyskanie elementu, który chcesz z tej listy.
l = list(myfunct())
l[4]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-19 21:58:52