检查迭代器是否至少生成一个元素的单行代码?
目前我正在这样做:
try:
something = next(iterator)
# ...
except StopIteration:
# ...
但是我想要一个可以放在简单的 if
语句里的表达式。有内置的东西可以让这段代码看起来不那么笨重吗?我只需要检查第一个项目。
8 个回答
28
这其实并不是更简洁的写法,但它展示了一种可以无损地把代码封装成函数的方法:
def has_elements(iter):
from itertools import tee
iter, any_check = tee(iter)
try:
any_check.next()
return True, iter
except StopIteration:
return False, iter
has_el, iter = has_elements(iter)
if has_el:
# not empty
这并不是特别符合Python的风格,而且在某些特定情况下,可能会有更好的解决方案(虽然这些方案不够通用),比如next的默认值。
first = next(iter, None)
if first:
# Do something
这并不通用,因为在很多可迭代对象中,None可能是一个有效的元素。
65
将一个哨兵值作为next()
的默认值传入:
sentinel = object()
if next(iterator, sentinel) is sentinel:
print('iterator was empty')
你还可以使用任何你“知道”的值(根据应用的具体情况)作为哨兵值,这个值是迭代器绝对不会返回的。
183
if any(True for _ in iterator):
print('iterator had at least one element')
if all(False for _ in iterator):
print('iterator was empty')
请注意,如果这个可迭代对象至少有一个元素,这个操作会消耗掉第一个元素。