是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
建议:
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.
其他回答
在Mark Ransom的提示下,这里有一个类,你可以使用它来包装任何迭代器,这样你就可以提前查看,将值推回流并检查是否为空。这是一个简单的想法和简单的实现,我发现在过去非常方便。
class Pushable:
def __init__(self, iter):
self.source = iter
self.stored = []
def __iter__(self):
return self
def __bool__(self):
if self.stored:
return True
try:
self.stored.append(next(self.source))
except StopIteration:
return False
return True
def push(self, value):
self.stored.append(value)
def peek(self):
if self.stored:
return self.stored[-1]
value = next(self.source)
self.stored.append(value)
return value
def __next__(self):
if self.stored:
return self.stored.pop()
return next(self.source)
>>> gen = (i for i in [])
>>> next(gen)
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
next(gen)
StopIteration
在生成器结束时引发StopIteration,因为在您的情况下立即到达结束,因此引发异常。但通常你不应该检查下一个值是否存在。
你可以做的另一件事是:
>>> gen = (i for i in [])
>>> if not list(gen):
print('empty 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]
对于这种显而易见的方法,我很抱歉,但最好的方法是:
for item in my_generator:
print item
现在您已经检测到在使用生成器时它是空的。当然,如果生成器为空,项将永远不会显示。
这可能不完全适合您的代码,但这就是生成器的习惯用法:迭代,所以您可能会稍微改变您的方法,或者根本不使用生成器。
一种简单的方法是使用next()的可选参数,如果生成器耗尽(或为空),则使用该参数。例如:
_exhausted = object()
if next(some_generator, _exhausted) is _exhausted:
print('generator is empty')
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录