Python是否有任何等效的for循环(不是foreach)
Python的迭代器非常棒,但有时我确实需要C风格的for循环,而不是foreach循环。例如,我有一个开始日期和一个结束日期,我想在这个范围内每天做些事情。当然,我可以通过while循环来实现这一点:Python是否有任何等效的for循环(不是foreach),python,loops,for-loop,Python,Loops,For Loop,Python的迭代器非常棒,但有时我确实需要C风格的for循环,而不是foreach循环。例如,我有一个开始日期和一个结束日期,我想在这个范围内每天做些事情。当然,我可以通过while循环来实现这一点: current = start while current <= finish: do_stuff(current) current += timedelta(1) current=start 虽然当前只是为了迭代,但实际上应该在范围上使用
current = start
while current <= finish:
do_stuff(current)
current += timedelta(1)
current=start
虽然当前只是为了迭代,但实际上应该在范围上使用xrange,因为xrange将简单地返回一个迭代器,而range将创建一个实际的列表对象,其中包含从第一个到最后一个-1的整个整数范围(当您只需要一个简单的For循环时,这显然效率较低):
此外,还有enumerate,它返回一个enumerate对象,该对象将产生递增计数和集合值,即:
l = ["a", "b", "c"]
for ii, value in enumerate(l):
print ii, value
结果:
0 a
1 b
2 c
优雅的python方法是将日期范围的概念封装在自己的生成器中,然后在代码中使用该生成器:
import datetime
def daterange(start, end, delta):
""" Just like `range`, but for dates! """
current = start
while current < end:
yield current
current += delta
start = datetime.datetime.now()
end = start + datetime.timedelta(days=20)
for d in daterange(start, end, datetime.timedelta(days=1)):
print d
这与关于range
的答案类似,只是内置的range
不能与日期时间一起工作,因此我们必须创建自己的,但至少我们可以以封装的方式只做一次。以紧凑的方式做在Python中并不容易,作为语言背后的一个基本概念,我们不能对比较进行赋值
对于一些复杂的事情,比如日期,我认为Ned的答案很好,但是对于更简单的情况,我发现itertools.count()函数非常有用,它返回连续的数字
>>> import itertools
>>> begin = 10
>>> end = 15
>>> for i in itertools.count(begin):
... print 'counting ', i
... if i > end:
... break
...
counting 10
counting 11
counting 12
counting 13
counting 14
counting 15
counting 16
我发现它不太容易出错,正如您所说,忘记“current+=1”很容易。对我来说,创建一个无限循环,然后检查结束条件似乎更为自然。这将在紧要关头起作用:
def cfor(start, test_func, cycle_func):
"""A generator function that emulates the most common case of the C for
loop construct, where a variable is assigned a value at the begining, then
on each next cycle updated in some way, and exited when a condition
depending on that variable evaluates to false. This function yields what
the value would be at each iteration of the for loop.
Inputs:
start: the initial yielded value
test_func: called on the previous yielded value; if false, the
the generator raises StopIteration and the loop exits.
cycle_func: called on the previous yielded value, retuns the next
yielded value
Yields:
var: the value of the loop variable
An example:
for x in cfor(0.0, lambda x: x <= 3.0, lambda x: x + 1.0):
print x # Obviously, print(x) for Python 3
prints out
0.0
1.0
2.0
3.0
"""
var = start
while test_func(var):
yield var
var = cycle_func(var)
def cfor(启动、测试功能、循环功能):
“”“一个生成器函数,用于模拟最常见的C
循环构造,其中变量在开始时被赋值,然后
在下一个循环中,以某种方式更新,并在出现条件时退出
根据变量的不同,该函数的计算结果为false
该值将出现在for循环的每次迭代中。
投入:
开始:初始屈服值
test_func:对上一个生成的值调用;如果为false,则
生成器引发StopIteration,循环退出。
cycle_func:调用上一个生成的值,重新运行下一个值
屈服值
产量:
var:循环变量的值
例如:
对于cfor中的x(0.0,lambda x:x+1),不仅因为它是唯一有效的答案,而且因为它是正确的答案。说真的,不要投票支持看起来很好的答案—在发布前测试答案。结果是TypeError:需要一个整数
。xrange()的所有参数
必须是整数。xrange
应该被命名为irange
,因为它返回一个迭代器,而range
应该总是返回一个列表;xrange
的唯一约束应该是next=start;next=next+step;直到next==end
,也就是说start
必须是\uu add
步骤
并且结果必须是\uuu cmp\uuuu
能够结束
WTF?为什么不在xrange(开始,结束)中的i使用?
>>> import itertools
>>> begin = 10
>>> end = 15
>>> for i in itertools.count(begin):
... print 'counting ', i
... if i > end:
... break
...
counting 10
counting 11
counting 12
counting 13
counting 14
counting 15
counting 16
def cfor(start, test_func, cycle_func):
"""A generator function that emulates the most common case of the C for
loop construct, where a variable is assigned a value at the begining, then
on each next cycle updated in some way, and exited when a condition
depending on that variable evaluates to false. This function yields what
the value would be at each iteration of the for loop.
Inputs:
start: the initial yielded value
test_func: called on the previous yielded value; if false, the
the generator raises StopIteration and the loop exits.
cycle_func: called on the previous yielded value, retuns the next
yielded value
Yields:
var: the value of the loop variable
An example:
for x in cfor(0.0, lambda x: x <= 3.0, lambda x: x + 1.0):
print x # Obviously, print(x) for Python 3
prints out
0.0
1.0
2.0
3.0
"""
var = start
while test_func(var):
yield var
var = cycle_func(var)