Генератордан бір элемент қалай таңдалады (питонда)?

Менің генераторлық функциясы бар, мысалы:

 def myfunct(): ... yield result 

Бұл функцияны әдеттегі тәсіл деп атауға болады:

 for r in myfunct(): dostuff(r) 

Менің сұрағым - генератордан тек бір нәрсені ғана ұнататын бір жол бар ма? Мысалы, мен бірдеңе істеуді қалаймын:

 while True: ... if something: my_element = pick_just_one_element(myfunct()) dostuff(my_element) ... 
105
20 янв. Александрович 20 қаңтарда тағайындалды 2011-01-20 00:55 '11 at 0:55 2011-01-20 00:55
@ 5 жауаптар

Генераторды қолданыңыз

 g = myfunct() 

Элементті пайдаланғыңыз келген сайын пайдаланыңыз

 g.next() 

немесе

 next(g) 

Егер генератор StopIteration қалса, онда ол StopIteration . Қажет болған жағдайда бұл ерекшелікті ұстай аласыз немесе next() үшін default аргументін қолдануға болады:

 next(g, default_value) 
153
20 янв. Жауап Свен Марнач 20 қаңтар 2011-01-20 00:58 '11 at 0:58 2011-01-20 00:58

Бір генератор элементін таңдау үшін, break for немесе өрнек list(itertools.islice(gen, 1))

Сіздің мысалыңызға сәйкес (сөзбе-сөз) мына әрекеттерді орындауға болады:

 while True: ... if something: for my_element in myfunct(): dostuff(my_element) break else: do_generator_empty() 

Егер сіз «ұнаған кезде генератордан бір ғана элемент алуды» қаласаңыз (менің ойымша, 50% - бұл бастапқы мақсат және ең көп таралған ниет).

 gen = myfunct() while True: ... if something: for my_element in gen: dostuff(my_element) break else: do_generator_empty() 

Осылайша generator.next() -тың нақты пайдалануын болдырмауға болады және I / O өңдеуі (ерекше) ерекше жағдайларды StopIteration немесе әдепкі мәндерді қосымша салыстыруды талап етпейді.

border=0

else: егер сіз генератордың соңында ерекше нәрсе жасауды қаласаңыз, тармақ for қажет.

next() / .next() :

Python3-те, .next() әдісі .__next__() атауына жақсы себеппен өзгертілді: оның төмен деңгейі (PEP 3114). Python 2.6 алдында, next() кірістірілген функция жоқ. Және сирек қажеттілікке және кіріктірілген атаулардың күмәнді инфляциясына байланысты operator модульге () ақылға қонымды түрде өту үшін талқыланды.

Әдепкі бойынша next() қолдану өте төмен деңгейлі тәжірибе болып табылады - ашық түрде StopIteration ді көгілдір түсті болт ретінде қарапайым қолданба кодын енгізіңіз. Ал next() функциясын әдепкі мәнмен пайдалану - осыдан next() тікелей next() тікелей next() арналған жалғыз нұсқа болуы керек - шектеулі және көбінесе төтенше емес пификалық логика / оқылуды тудырады.

Bottom line: Келесі () пайдалану өте сирек болуы керек - мысалы, operator модулінің функцияларын пайдалану. for x in iterator , islice , list(iterator) және басқа да функцияларды қолдану islice қолдану деңгейінде қолданудың табиғи жолы болып табылады - және мүмкін. next() - төмен деңгейлі, бірін-бірі толықтыратын тұжырымдамасы, айқын емес - бұл жіп туралы сұрақ бойынша. Дегенмен, мысалы, break қолданылуы әдетте қабылданады.

10
12 февр. Жауапқа kxr 12 ақпан берілді. 2016-02-12 21:48 '16 at 21:48 2016-02-12 21:48

Генератордан ерікті мәнді алудың ыңғайлы жолы бар деп ойлаймын. Генератор жылжытуға келесі әдісті () береді, бірақ жадты үнемдеу үшін толық тізбектеу дереу жасалмайды. Бұл генератор мен тізім арасындағы функционалдық айырмашылық.

2
20 янв. жауап 20 қаңтар күні gddc арқылы беріледі 2011-01-20 00:59 '11 at 0:59 2011-01-20 00:59
 generator = myfunct() while True: my_element = generator.next() 

Соңғы элементтен кейін жасалған ерекшелікті ұстаңыз.

0
20 янв. Жауапты Джон 20 қаңтарда берген . 2011-01-20 01:01 '11 at 1:01 2011-01-20 01:01

Мен жалғыз әдіс - бұл иератордан тізім алу, содан кейін сол тізімнен элементті алу.

 l = list(myfunct()) l[4] 
-1
20 янв. жауап keegan3d 20 қаңтар 2011-01-20 00:58 '11 at 0:58 2011-01-20 00:58

тегтеріне қатысты басқа сұрақтар немесе Сұрақ қою