Генерировать из генераторов
Вопрос
У меня есть генератор, который принимает число в качестве аргумента и выдает другие числа.Я хочу использовать числа, полученные этим генератором, и передать их в качестве аргументов тому же генератору, создав цепочку некоторой длины.
Например, mygenerator(2) выдает значения 5, 4 и 6.Примените mygenerator к каждому из этих чисел, снова и снова к полученным числам.Генератор всегда выдает большие числа, чем то, которое передано в качестве аргумента, и для 2 разных чисел никогда не выдаст одно и то же число.
мой генератор (2):4 5 мой генератор (4) :10 11 12 мой генератор (5):9 300 500
Таким образом, множество (9,10,11,12,300,500) имеет "расстояние" 2 от исходного числа, 2.Если я применю это к числу 9, я получу набор чисел с расстоянием "3" от исходного 2.
По сути, я хочу создать набор, который имеет указанное расстояние от заданного числа, и у меня возникают проблемы с выяснением, как это сделать в Python.Помощь очень ценится :)
Решение
Это решение не требует сохранения всех результатов в памяти:(на случай, если он не помещается в памяти и т.д.)
def grandKids(generation, kidsFunc, val):
layer = [val]
for i in xrange(generation):
layer = itertools.chain.from_iterable(itertools.imap(kidsFunc, layer))
return layer
Пример:
def kids(x): # children indices in a 1-based binary heap
yield x*2
yield x*2+1
>>> list(grandKids(3, kids, 2))
[16, 17, 18, 19, 20, 21, 22, 23]
Кстати, решение на Haskell:
grandKids generation kidsFunc val =
iterate (concatMap kidsFunc) [val] !! generation
Другие советы
Предположим, что наш генератор выдает квадрат и куб с заданным числом таким образом, что он выдаст уникальный так что если мы хотим получить числа на расстоянии D в простейшем случае, мы можем рекурсивно получить числа на расстоянии D-1, а затем применить к ним генератор
def mygen(N):
yield N**2
yield N**3
def getSet(N, dist):
if dist == 0:
return [N]
numbers = []
for n in getSet(N, dist-1):
numbers += list(mygen(n))
return numbers
print getSet(2,0)
print getSet(2,1)
print getSet(2,2)
print getSet(2,3)
вывод
[2]
[4, 8]
[16, 64, 64, 512]
[256, 4096, 4096, 262144, 4096, 262144, 262144, 134217728]
Я только начал изучать Python, так что терпите меня, если мой ответ кажется немного любительским. Что вы можете сделать, это использовать список списков для заполнения значений, возвращаемых функцией myGenerator.
Так, например. с 2 в качестве начального аргумента ваша структура данных будет выглядеть примерно так
resDataSet = [[2],
[4, 5],
[9, 10, 11, 12, 300 , 500]
...
]
Индекс строки должен указывать вам расстояние, и вы можете использовать такие методы, как extended, чтобы добавить больше данных в ваш список.