从生成器生成
我有一个生成器,它接受一个数字作为参数,然后输出其他数字。我想利用这个生成器输出的数字,再把它们作为参数传回给同一个生成器,这样就能形成一个链条,链条的长度可以变化。
举个例子,我调用mygenerator(2)会得到5、4和6这几个数字。然后我对这些数字再调用mygenerator,反复进行这个操作。这个生成器总是输出比传入的参数大的数字,而且对于两个不同的数字,它不会输出相同的数字。
比如说: mygenerator(2): 4 5 mygenerator(4): 10 11 12 mygenerator(5): 9 300 500
这样,数字集合(9, 10, 11, 12, 300, 500)与原始数字2的“距离”是2。如果我对数字9再调用一次生成器,就会得到一个与原始数字2的距离为“3”的数字集合。
总的来说,我想创建一个与给定数字有特定距离的数字集合,但我在Python中不知道该怎么做。希望能得到一些帮助 :)
3 个回答
0
我刚开始学习Python,所以如果我的回答听起来有点幼稚,请多包涵。你可以使用一个列表的列表来存储从myGenerator函数返回的值。
比如说,如果你用2作为起始参数,你的数据结构看起来会像这样:
resDataSet = [[2],
[4, 5],
[9, 10, 11, 12, 300 , 500]
...
]
行的索引可以告诉你距离,你还可以使用像extend这样的方式来往你的列表里添加更多的数据。
3
假设我们的生成器可以输出一个数字的平方和立方,这样它的输出就是独一无二的。如果我们想要得到距离 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]
2
这个解决方案不需要把所有结果都保存在内存里:比如说,当结果太大,放不下的时候。
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