用于计算循环执行的Python习惯用法

pet*_*rjc 4 python for-loop idioms idiomatic

如果循环遍历list/tuple/sequence,则可以len(...)用来推断循环执行的次数.但是当循环遍历迭代器时,你不能.

[ 为清晰起见更新:我正在考虑一次性使用有限迭代器,我想对项目进行计算并同时计算它们.]

我目前使用显式计数器变量,如下例所示:

def some_function(some_argument):
    pass


some_iterator = iter("Hello world")

count = 0
for value in some_iterator:
    some_function(value)
    count += 1

print("Looped %i times" % count)
Run Code Online (Sandbox Code Playgroud)

鉴于有11个字符"Hello world",这里的预期输出是:

Looped 11 times
Run Code Online (Sandbox Code Playgroud)

我也考虑过这个较短的替代方案,enumerate(...)但我不觉得这很清楚:

def some_function(some_argument):
    pass


some_iterator = iter("Hello world")

count = 0  # Added for special case, see note below
for count, value in enumerate(some_iterator, start=1):
    some_function(value)

print("Looped %i times" % count)
Run Code Online (Sandbox Code Playgroud)

[ 更新供参考:@mata发现,如果迭代器为空,那么第二个例子在最初编写时会失败.插入count = 0解决了这个,或者我们可以使用该for ... else ...结构来处理这个角落的情况.]

它不使用enumerate(...)循环内的索引,而是将变量设置为循环计数几乎是一个副作用.对我来说这是非常不清楚的,所以我更喜欢第一个带有显式增量的版本.

是否有一种可接受的Pythonic方法(理想情况下是Python 3和Python 2代码)?

900*_*000 5

enumerate如果循环没有通过添加一行来运行,您可以将方便性与定义的计数器结合起来:

count = 0  # Counter is set in any case.
for count, item in enumerate(data, start=1):
   doSomethingTo(item)
print "Did it %d times" % count
Run Code Online (Sandbox Code Playgroud)

如果您只需要计算迭代器中的项目数,而不对项目执行任何操作,并且没有列出它们,则可以简单地执行以下操作:

count = sum(1 for ignored_item in data)  # count a 1 for each item
Run Code Online (Sandbox Code Playgroud)


blu*_*ote 1

无法获取迭代器中的项目数。想想这个案例

def gen():
   a = 1
   while True:
       yield a
       a += 1
f = gen()

for value in f:
    # do something
Run Code Online (Sandbox Code Playgroud)

这个迭代器的大小是多少?迭代器在以下情况下结束,并且如果,它引发StopIteration。相反,当您迭代一个序列时,该序列已经存在,因此可以知道它的长度。

您使用的两种方法都很好。最好取决于你的口味。另一种选择是使用

from itertools import count
for item, counter in zip(iterator, count()):
    # do stuff
Run Code Online (Sandbox Code Playgroud)

但是,我认为在大多数情况下,您的第一种传统方法会更清晰。