是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
对于这种显而易见的方法,我很抱歉,但最好的方法是:
for item in my_generator:
print item
现在您已经检测到在使用生成器时它是空的。当然,如果生成器为空,项将永远不会显示。
这可能不完全适合您的代码,但这就是生成器的习惯用法:迭代,所以您可能会稍微改变您的方法,或者根本不使用生成器。
其他回答
对你的问题的简单回答是:不,没有简单的方法。有很多变通办法。
不应该有一种简单的方法,因为生成器是一种输出值序列而不将序列保存在内存中的方法。所以没有向后遍历。
你可以写一个has_next函数,或者甚至可以把它作为一个带有花哨装饰器的方法放在生成器上。
为了表达我的“2美分”,我将描述一下我的经历:
我有一个生成器,我需要用itertools切片它。分成小发电机。然后检查我的子生成器是否为空,我只是将它们转换/消耗到一个小列表中,然后检查列表是否为空。
例如:
from itertools import islice
def generator(max_yield=10):
a = 0
while True:
a += 1
if a > max_yield:
raise StopIteration()
yield a
tg = generator()
label = 1
while True:
itg = list(islice(tg, 3))
if not itg: # <-- I check if the list is empty or not
break
for i in itg:
print(f'#{label} - {i}')
label += 1
输出:
#1 - 1
#1 - 2
#1 - 3
#2 - 4
#2 - 5
#2 - 6
#3 - 7
#3 - 8
#3 - 9
#4 - 10
也许这不是最好的方法,主要是因为它会消耗生成器,但对我来说却是可行的。
下面是一个包装生成器的简单装饰器,因此如果为空,它将返回None。如果您的代码需要知道生成器在循环遍历之前是否会生成任何东西,那么这可能很有用。
def generator_or_none(func):
"""Wrap a generator function, returning None if it's empty. """
def inner(*args, **kwargs):
# peek at the first item; return None if it doesn't exist
try:
next(func(*args, **kwargs))
except StopIteration:
return None
# return original generator otherwise first item will be missing
return func(*args, **kwargs)
return inner
用法:
import random
@generator_or_none
def random_length_generator():
for i in range(random.randint(0, 10)):
yield i
gen = random_length_generator()
if gen is None:
print('Generator is empty')
一个有用的例子是在模板代码中—即jinj2
{% if content_generator %}
<section>
<h4>Section title</h4>
{% for item in content_generator %}
{{ item }}
{% endfor %
</section>
{% endif %}
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(),则此方法有效。
对于这种显而易见的方法,我很抱歉,但最好的方法是:
for item in my_generator:
print item
现在您已经检测到在使用生成器时它是空的。当然,如果生成器为空,项将永远不会显示。
这可能不完全适合您的代码,但这就是生成器的习惯用法:迭代,所以您可能会稍微改变您的方法,或者根本不使用生成器。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录