通常,您不需要在表达式中使用它,因此您只需调用 next(it),忽略结果,使用并丢弃第一个元素。
但是,如果迭代器可能为空,您必须决定要发生什么:
- 也许你想提高
StopIteration,在这种情况下next(it) 很好。
- 也许您想提出其他问题,在这种情况下,您将
next(it) 放在 except StopIteration: raise SomethingElse() 中。
- 也许您只想将迭代器留空,在这种情况下您可以调用
next(it, None)。
您可以在标准库和文档中找到这些示例。例如,如果您浏览 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 部分;有趣的是,它跳过了带有islice 和next 的n 元素。 (请注意,它正在原地变异 iterator,而不是返回任何东西。)