[英]Get multiple individual values from generator in Python
How do i take multiple arbitrary values from different index positions in an iterator? 如何从迭代器的不同索引位置获取多个任意值?
How to get the n next values of a generator in a list (python) and Get the nth item of a generator in Python describe the use of itertools.islice
for taking arbitrary element or continuous subset from an iterator. 如何在列表(python)中 获取 生成器的n个下一个值以及如何 在Python中获取生成器的n个项,描述了itertools.islice
用于从迭代器获取任意元素或连续子集的用法。 But what if i want multiple arbitrary elements from different positions in the iterator, where you can't just use islice
's step argument? 但是,如果我想要迭代器中不同位置的多个任意元素,而不能仅仅使用islice
的step参数呢?
I'm trying to solve Project Euler's problem 40 . 我正在尝试解决Euler项目的问题40 。 I generated a string of concatenated integers with 我生成了一个由串联的整数组成的字符串
iteration = (i for i in ''.join(map(str, (i for i in xrange(1,10**6)))))
An now i want to get elements with indexes 1, 10, 100, 1000, 10000, 100000, 1000000 counting from 1. I couldn't use islice
here, because every call to next
shifts current value to yield to the right. 现在,我想从索引1开始获得索引为islice
在这里我不能使用islice
,因为每次调用next
都会使当前值右移。 For example 例如
next(islice(iteration, 1, 2)) + next(islice(iteration, 3, 4))
produces '26' instead of '24'. 产生“ 26”而不是“ 24”。
Update (25.11.12, 4:43 UTC+0) : 更新(25.11.12,4:43 UTC + 0) :
Thanks for all the suggestions. 感谢所有的建议。 My current code looks like: 我当前的代码如下:
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)
The ugly argument for nth
is to generate a sequence of 0, 8, 89, 899, 8999 etc. nth
的丑陋参数是生成0、8、89、899、8999等的序列。
(Note that there are much faster ways to solve Euler #40.) (请注意,有更快的方法可以解决Euler#40。)
I would work a little differently. 我的工作方式会有所不同。 Instead of using nth
: 而不是使用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]
This way I don't have to do any subtractions to make sure I have the right indices. 这样,我不必进行任何减法操作即可确保索引正确。
This is from the "recipes" section of the itertools documentation . 这是来自itertools文档的“食谱”部分 。 It returns the n
th element of iterable
, consuming it as it goes: 它返回iterable
第n
个元素,并随其使用:
def nth(iterable, n, default=None):
"Returns the nth item or a default value"
return next(islice(iterable, n, None), default)
You can get the 1st, 10th, 100th etc elements by calling it sequentially (noting that the iterator gets consumed, and is zero-indexed): 您可以通过依次调用它来获得1st,10th,100th等元素(请注意,迭代器已消耗,并且索引为零):
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
Alternatively, you could use tee
and use nth
with a different iterator each time. 另外,您可以每次使用tee
并使用nth
和不同的迭代器。 This way you don't have to worry about the fact that your single iterator is getting consumed. 这样,您不必担心单个迭代器被消耗的事实。 On the other hand you might start swallowing memory if your iterators are very long. 另一方面,如果迭代器很长,则可能开始吞下内存。
As well as looking at nth
as mentioned - I would look at simplifying your generator: 就像提到的那样查看nth
我将着眼于简化生成器:
from itertools import count
def concat():
for i in count(1):
for j in str(i):
yield int(j)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.