如何从迭代器中的不同索引位置获取多个任意值?
How to get the n next values of a generator in a list (python)和Get the nth item of a generator in Python描述了使用itertools.islice
从迭代器中获取任意元素或连续子集。但是如果我想在迭代器中使用来自不同位置的多个任意元素,那么你不能只使用islice
的步骤参数呢?
我正在尝试解决Project Euler的problem 40。我用
生成了一串连接的整数iteration = (i for i in ''.join(map(str, (i for i in xrange(1,10**6)))))
现在我想从1开始获取索引1,10,100,1000,10000,100000,1000000的元素。我在这里无法使用islice
,因为每次调用next
将当前值转移到右边。例如
next(islice(iteration, 1, 2)) + next(islice(iteration, 3, 4))
产生'26'而不是'24'。
更新(25.11.12,4:43 UTC + 0):
感谢所有建议。我目前的代码如下:
it = (i for i in ''.join(map(str, (i for i in xrange(1,10**6)))))
ds = [int(nth(it, 10**i-10**(i-1)-1)) for i in range(7)]
return product(ds)
nth
的丑陋论据是生成0,8,89,899,8999等序列。
答案 0 :(得分:4)
(请注意,有更快的方法可以解决Euler#40。)
我的工作方式会有所不同。而不是使用nth
:
>>> from itertools import chain, count, islice
>>>
>>> it = chain.from_iterable(str(i) for i in count(1))
>>> wanted = {10**i for i in range(7)}
>>> scan_region = islice(it, max(wanted)+1)
>>> digits = [int(x) for i, x in enumerate(scan_region, 1) if i in wanted]
>>> digits
[1, 1, 5, 3, 7, 2, 1]
这样我就不必做任何减法以确保我有正确的索引。
答案 1 :(得分:1)
这是the "recipes" section of the itertools documentation。它返回n
的{{1}}元素,并按原样使用它:
iterable
你可以通过顺序调用它来获取第1个,第10个,第100个等元素(注意迭代器被消耗,并且是零索引的):
def nth(iterable, n, default=None):
"Returns the nth item or a default value"
return next(islice(iterable, n, None), default)
或者,您可以使用first = nth(iteration, 0)
tenth = nth(iteration, 8) # since we've already taken one
hundredth = nth(iteration, 89) # since we've already taken ten
# etc
并使用tee
每次使用不同的迭代器。这样您就不必担心单个迭代器被消耗的事实。另一方面,如果你的迭代器很长,你可能会开始吞咽内存。
答案 2 :(得分:1)
除了如上所述查看nth
之外,我还会考虑简化您的生成器:
from itertools import count
def concat():
for i in count(1):
for j in str(i):
yield int(j)