Как получить результаты от вложенной функции генератора?
У меня есть функция, которая дает результаты по мере их загрузки. Для целей этого вопроса, скажем, я даю укус один раз в секунду, но я хочу, чтобы функция удобства обертывала мой генератор:
import time
def GeneratorFunction(max_val):
for i in range(0,5):
time.sleep(1)
yield "String %d"%i
def SmallGenerator():
yield GeneratorFunction(3)
for s in SmallGenerator():
print s
... почему это не так просто напечатать 5 строк, которые я ожидаю? Вместо этого он возвращает функцию генератора:
<generator object GeneratorFunction at 0x020649B8>
Как я могу заставить это привести строки, поскольку нормальная функция генератора будет?
Ответы
Ответ 1
ОБНОВЛЕНИЕ На основе комментария @Martin Pieters, гораздо лучший подход будет просто.
def SmallGenerator(): return GeneratorFunction(3)
SmallGenerator должен быть что-то вокруг:
def SmallGenerator():
for item in GeneratorFunction(3):
yield item
В вашей реализации SmallGenerator выдает фактический генератор, а не элементы, сгенерированные им.
Ответ 2
Не могу поверить, что я пропустил это; Ответ заключается в том, чтобы просто вернуть функцию генератора с подходящими аргументами:
import time
def GeneratorFunction(max_val):
for i in range(0,max_val):
time.sleep(1)
yield "String %d"%i
def SmallGenerator():
return GeneratorFunction(3) # <-- note the use of return instead of yield
for s in SmallGenerator():
print s
Ответ 3
Возможно, вам придется использовать новый yield from
, доступный с Python 3.3, называемый делегированный генератор.
Если я правильно понял вопрос, я пришел к той же проблеме и нашел ответ в другом месте.
Я хотел сделать что-то вроде этого:
def f():
def g():
do_something()
yield x
…
yield y
do_some_other_thing()
yield a
…
g() # Was not working.
yield g() # Was not what was expected neither; yielded None.
…
yield b
Теперь я использую это вместо:
yield from g() # Now it works, it yields x and Y.
Я получил ответ с этой страницы: Python 3: Использование "yield from" в Generators - Part1 (simeonvisser.com).
Ответ 4
Пришел сюда искать другую форму "вложенной доходности" и, наконец, нашел скрытый ответ. Не может быть лучшим, но он работает.
Я хотел уступить через дерево реестра, и вот решение.
def genKeys(key):
for value in key.values():
yield value
for subkey in key.subkeys():
print(subkey)
for x in genKeys(subkey): #this is the trick
continue
Ответ 5
Вот еще один небольшой пример для создания таблицы умножения от 1 до 10:
class Gen1:
def __init__(self, gen2):
self.gen2 = gen2
def __iter__(self):
for a in range(1, 11):
for b in self.gen2:
yield a * b
class Gen2:
def __iter__(self):
for a in range(1, 11):
yield a
def main():
gen2 = Gen2()
gen1 = Gen1(gen2)
for v in gen1:
print(v)
if __name__ == '__main__':
main()
Ответ 6
Я пришел в поисках другого использования вложенных доходностей..
list_of_lists = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
def iter_all(foo):
yield foo
if isinstance(foo, list):
for i in foo:
for x in iter_all(i):
yield x
print([i for i in iter_all(list_of_lists)])
выход:
[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [1, 2, 3], 1, 2, 3, [4, 5, 6], 4, 5, 6, [7, 8, 9], 7, 8, 9]