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")