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代码)?
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)
无法获取迭代器中的项目数。想想这个案例
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)
但是,我认为在大多数情况下,您的第一种传统方法会更清晰。