我有一个生成器函数A
。
例如(实际上我有一个更复杂的功能A
),
def A():
yield from [i**2 for i in range(20)]
编写另一个生成器函数B
,我想枚举A
除第一个元素外的所有返回元素。
在Python 3中有哪些简单的方法可以实现此目的?
通常,您不需要在表达式中使用它,因此您只需调用next(it)
,而忽略结果即可消耗和丢弃第一个元素。
但是,如果迭代器可能为空,则必须决定要发生的事情:
StopIteration
,在这种情况下next(it)
可以。next(it)
进入except StopIteration: raise SomethingElse()
。next(it, None)
。您可以在stdlib和docs中找到这些示例。例如,如果您浏览中的配方itertools
:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
这正是您想要做的—跳过的第一个元素b
。如果iterable
为空,则您不希望在这里出错;您只想不进行任何迭代。因此,next(b, None)
。
如果您需要在表达式中间执行此操作怎么办?
然后,您可以编写一个跳过第一个元素的函数:
def skip_first(iterable):
it = iter(iterable)
next(it, None)
return it
(同样,您必须决定要为空的可迭代对象进行的操作。)
这将返回迭代器的第一个跳过版本,因此您可以内联使用它。(它也发生变异的迭代器是传入的,当然,但你通常只在一个临时的值,你没有保留任何引用来使用,所以这不是一个问题。)
或者,如果您需要返回一个生成器而不是一个任意迭代器(通常不需要):
def skip_first(iterable):
it = iter(iterable)
next(it, None)
yield from it
或者,您可以使用相同想法的更通用版本itertools.islice
。以下具有相同的效果:
it = skip_first(it)
it = itertools.islice(it, 1, None)
当我们使用itertools
食谱时,值得一看consume
:
def consume(iterator, n=None):
"Advance the iterator n-steps ahead. If n is None, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
忘记None
部分;有趣的是,它会跳过n
带有islice
和的元素next
。(请注意,它是iterator
就地变异,不返回任何内容。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句