是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
Bool (generator)将返回正确的结果
其他回答
使用cytoolz中的peek函数。
from cytoolz import peek
from typing import Tuple, Iterable
def is_empty_iterator(g: Iterable) -> Tuple[Iterable, bool]:
try:
_, g = peek(g)
return g, False
except StopIteration:
return g, True
此函数返回的迭代器将等效于作为参数传入的原始迭代器。
一种简单的方法是使用next()的可选参数,如果生成器耗尽(或为空),则使用该参数。例如:
_exhausted = object()
if next(some_generator, _exhausted) is _exhausted:
print('generator is empty')
建议:
def peek(iterable):
try:
first = next(iterable)
except StopIteration:
return None
return first, itertools.chain([first], iterable)
用法:
res = peek(mysequence)
if res is None:
# sequence is empty. Do stuff.
else:
first, mysequence = res
# Do something with first, maybe?
# Then iterate over the sequence:
for element in mysequence:
# etc.
Quick-dirty解决方案:
next(generator, None)不是None
或者将None替换为任何你知道不在生成器中的值。
编辑:是的,这将跳过生成器中的一项。然而,有时我只是出于验证目的检查生成器是否为空,然后并不真正使用它。否则我就会这样做:
def foo(self):
if next(self.my_generator(), None) is None:
raise Exception("Not initiated")
for x in self.my_generator():
...
也就是说,如果您的生成器来自一个函数,如my_generator(),则此方法有效。
刚刚读到这篇文章,意识到缺少一个非常简单易懂的答案:
def is_empty(generator):
for item in generator:
return False
return True
如果我们不打算使用任何项,那么我们需要将第一项重新注入生成器:
def is_empty_no_side_effects(generator):
try:
item = next(generator)
def my_generator():
yield item
yield from generator
return my_generator(), False
except StopIteration:
return (_ for _ in []), True
例子:
>>> g=(i for i in [])
>>> g,empty=is_empty_no_side_effects(g)
>>> empty
True
>>> g=(i for i in range(10))
>>> g,empty=is_empty_no_side_effects(g)
>>> empty
False
>>> list(g)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录