我使用的是Python 3.6.7。
我刚刚注意到,在空白列表上的for
循环甚至不会循环一次。
经过一番思考,这对我来说很有意义。即大小为零(空)的对象上的循环返回零次迭代。
iterable = []
for element in iterable:
pass
print(element)
>>> NameError: name 'element' is not defined
这意味着如果使用len(iterable) == 0
,则不会在循环内执行测试。
iterable = []
for element in iterable:
assert isinstance(element, int)
#nothing happens
那我该如何捕捉这种情况?
当由于iterable为空而导致循环不运行时,是否存在一种紧凑的内置方法来引发错误?
要适应这种特殊情况,需要手动进行:
iterator
是否为空我可能最终在每个for
循环中都要进行此测试。
assert len(iterable) > 0
#loop
或
#loop
assert "element" in dir() #?
答案 0 :(得分:2)
您可以使用Statements, and else Clauses on Loops。
循环语句可以包含
else
子句;当循环通过穷尽迭代器终止时执行。
例如:
iterator = []
for element in iterator:
print('This wont print..')
else:
assert iterator
这将导致:
Traceback (most recent call last):
File "<pyshell#2>", line 4, in <module>
assert iterator
AssertionError
答案 1 :(得分:2)
如果由于列表为空而导致循环无法运行,为什么还要执行某些操作?这是完全正常的行为。如果您出于某种原因期望至少有一个项目(也许数组中没有项目可以衡量程序中的错误),请按照前面的建议检查是否len(iterator) == 0
。这是一种完全有效的方法。
在这种情况下,当您检查变量等的值时,应该使用exepties的方式。断言更多是针对严重故障的硬编码信息,不应用于报告常见错误,因为它们不能处理。
答案 2 :(得分:1)
没有内置的方法可以直接检查空的迭代器。空迭代器通常不被视为例外。但是,您可以定义紧凑型助手来显式检查空的迭代器。
通常不可能预先检测空的迭代器。在某些情况下,您可以从迭代器的源中猜测它是否为空-例如,如果序列和映射的迭代器的父级为boolean false,则它们为空。但是,迭代器本身没有任何内容指示,除非进行迭代,否则实际上可能是“空”的。
唯一可靠的方法是检查迭代器在迭代时是否提供项目。 可以定义一个包装迭代器,如果迭代器根本不提供任何项目,则会引发错误。
def non_empty(iterable):
"""Helper to ensure that ``iterable`` is not empty during iteration"""
iterator = iter(iterable)
try:
yield next(iterator) # explicitly check first item
except StopIteration:
raise LookupError(f'{iterable} is empty') from None
yield from iterator # forward iteration of later items
这样的帮助程序可以包装在迭代器和迭代器中,并可以在for
循环,显式iter
迭代器和任何其他迭代方案中使用。
>>> iterable = []
>>> for element in non_empty(iterable):
... assert isinstance(element, int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in non_empty
LookupError: [] is empty