2012-11-25 60 views
1

如何從迭代器中的不同索引位置獲取多個任意值?從Python生成器獲取多個單獨的值

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的step參數?

我想解決項目歐拉的problem 40。我產生級聯整數的字符串

iteration = (i for i in ''.join(map(str, (i for i in xrange(1,10**6))))) 

的,現在我想用指標1,10,100,1000,10000 100000元,從1百萬計數我不能在這裏使用islice,因爲每撥號next都會將當前值轉移到右側。例如

next(islice(iteration, 1, 2)) + next(islice(iteration, 3, 4)) 

產生'26'而不是'24'。

更新(12年11月25日,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等

+1

你當前的代碼有一個問題,它不會懶惰地生成數字(例如,將'10 ** 6'改爲'10 ** 7') - '''.join'將消耗它的通過。 – DSM

回答

1

這是從the "recipes" section of the itertools documentation的序列。它返回的iterablen個元素,因爲它去消費它:

def nth(iterable, n, default=None): 
    "Returns the nth item or a default value" 
    return next(islice(iterable, n, None), default) 

你可以得到1日,10日,通過調用它順序(注意,迭代器將被佔用,以及100等元素的索引從零開始):

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和使用nth,每次不同的迭代器。這樣你就不必擔心你的單個迭代器被佔用了。另一方面,如果你的迭代器很長,你可能會開始吞噬內存。

1

除了看nth提到 - 我想看看簡化您的發電機:

from itertools import count 

def concat(): 
    for i in count(1): 
     for j in str(i): 
      yield int(j) 
4

(請注意,有更快的方法來解決歐拉#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] 

這樣,我沒有做任何刪減,以確保我有合適的指數。