Python 如何记录迭代器产生n次或零次?
在我对迭代器进行了迭代并对每件事做了其他事情之后,我想在迭代器中记录事情的数量(而不是试图捕获一个空迭代器,比如) 我的直觉是使用Python 如何记录迭代器产生n次或零次?,python,Python,在我对迭代器进行了迭代并对每件事做了其他事情之后,我想在迭代器中记录事情的数量(而不是试图捕获一个空迭代器,比如) 我的直觉是使用枚举内置: def foo_yielder(): to_收益率=['foo','bar'] 对于x英寸到x英寸的产量: 产量x 对于枚举中的i,x(foo_yielder(),start=1): 打印(x) #现在记录我们打印了多少东西 打印(f“我们记录了{i}件事”) 但是如果迭代器没有任何结果,i永远不会被定义 如果这是Javascript,我会: `我们记录
枚举
内置:
def foo_yielder():
to_收益率=['foo','bar']
对于x英寸到x英寸的产量:
产量x
对于枚举中的i,x(foo_yielder(),start=1):
打印(x)
#现在记录我们打印了多少东西
打印(f“我们记录了{i}件事”)
但是如果迭代器没有任何结果,i
永远不会被定义
如果这是Javascript,我会:
`我们记录了${i| | 0}件事情`
从C中吸取教训,我们可以做到:
i = 0
for x in foo_yielder():
print(x)
i = i + 1
print("We logged " + i + " things.")
但不知何故,这似乎令人难以置信地站不住脚
这里有什么好办法吗?将其设置为在空列表上枚举,for循环上的
else
子句将始终在循环完成后执行,检查当前命名空间中是否存在I
。填空的print
语句实际上并不必要。我不知道它是否非常优雅,但对于else的习惯用法来说,它是一个很好的用例
for i, _ in enumerate([], start=1):
pass # do whatever you want here
else:
if "i" in dir():
print(f"Found {i} instances")
else:
print(f"Found instances")
当然,这假定您没有在其他地方使用i
作为变量
当然,稍微清洁(干燥等)
最简单的方法是在枚举
循环之前添加一个i=0
如果麻烦的是i=0
附加行不美观,您可以尝试以下方法:
添加一个“虚拟”迭代器,并将其添加到迭代器中。然后,将枚举
重置为从0
开始计数(默认设置)。这样,您可以确保枚举
将迭代至少一个项目(并将i
设置为0
),然后从1
中计算实际的迭代器:
来自itertools导入链的
对于枚举中的i,x(链([0],foo_yielder()):
通过
打印(f“我们记录了{i}件事”)
这就带来了另一个问题,x
总是在第一次迭代中充当虚拟对象。您可以使用循环中的条件来处理这个问题,但这会使代码更加复杂
最后,您可以使用try/except
包装最终打印:
试试看:
打印(f“我们记录了{i}件事”)
除名称错误外:
打印(f“我们记录了0件事”)
但同样,这只是更多的代码,而不是一个简单的i=0
我的特定用例与迭代数据库游标结果有关,以及如果查询没有返回结果该怎么办。为什么不将i=0
放在循环之前,然后如果循环没有关闭i
,您将输出0?另一个选项是使用if/else语句进行设置,但仅定义i
可能仍是最佳选项。您也可以在for
中使用else
语句loop@Gabip我想保持这个问题的一般性。刚刚添加了一个用例来激发你的兴奋和喜悦。这里的else子句有什么好处?如果完全删除else,也会有同样的效果。我喜欢它将行为明确地绑定到循环中,这样,如果将来进行更改,则更容易看到范围内的所有内容else
仅在在某个地方中断时才在语义上有用。我想我更喜欢你在comments@Andrew中的答案设置I=0
,然后使用enumerate。
for i, _ in enumerate([], start=1):
pass # do whatever you want here
else:
if "i" not in dir():
i = 0
print(f"We logged {i} things")