使用内置的assert
语句,是否有一种很好的Pythonic方法可以检测迭代中的空虚?我见过:
但我正在寻找使用断言的解决方案。以下看起来可以工作,但我不确定我是否遗漏了一些重要的可能异常:
a = [1, 2, 3]
b = []
assert a, 'a is empty'
assert b, 'b is empty'
提出此AssertionError
:
Traceback (most recent call last):
File "<ipython-input-9-185714f6eb3c>", line 5, in <module>
assert b, 'b is empty'
AssertionError: b is empty
答案 0 :(得分:4)
请记住,不要将container
(思考列表,集合,元组,词典,等等)与iterable
混淆(任何可能出现新状态的东西)。检查iterable
是否为空的唯一方法是#34;是尝试迭代它并找出它是否不会产生至少一个新状态。您可以自由地将其解释为iterable
正在&#34;空&#34;。
像这样的东西
def test_thing_is_empty(self): # We are in a unittest.Testcase
foo = iter([]) # Or any other iterable thing
try:
item = next(foo)
except StopIteration:
pass # This is what should happen
else:
self.fail("Expected foo to be empty, got %s" % (item, ))
还要记住,iterable
在技术上从来都不是真正的#34;空的&#34;。尽管不鼓励,但有时允许iterable
抛出一个StopIteration
,如果再次尝试,所有突然开始产生新元素。
因此无法assert
这个。你必须试着看看你是否失败了。如果你失败了,唯一真正的知识是iterable
现在没有产生新的状态(无论出于何种原因)。如果你得到一个项目,iterable
只会产生一个独特的,珍贵的雪花,可能永远不会再次重现(想想从堆栈中某处的网络插座读取)。
答案 1 :(得分:-2)
怎么样:
assert len(a), "a is empty"
它与assert a, ...
,list
和dict
对象的set
效果相同,但您可能会发现它看起来更清晰/更易于维护。
assert a, ...
和assert len(a), ...
都不能保证适用于任意迭代,但您可能会发现后者更可取,因为它会抛出没有{{的迭代的异常1}},而不是让断言通过假阳性。看起来没有完全通用的解决方案(即你无法构建一个可以打败它的迭代的解决方案)。