[英]Simulating C-style for loops in python
(即使这个标题会导致火焰,我意识到)
Python做出了深思熟虑的设计选择,让for
循环使用显式迭代,在大多数情况下,代码大大简化了。
但是,如果你的测试用例和更新函数很复杂,有时候构造一个iterable会很麻烦,所以我发现自己编写了以下while循环:
val = START_VAL
while <awkward/complicated test case>:
# do stuff
...
val = <awkward/complicated update>
这个问题是更新位于while
块的底部,这意味着如果我想在其中嵌入一个continue
,我必须:
使用重复代码进行复杂/ awkard更新,AND
冒着忘记它并让我的代码无限循环的风险
我可以去手动滚动一个复杂的迭代器:
def complicated_iterator(val):
while <awkward/complicated test case>:
yeild val
val = <awkward/complicated update>
for val in complicated_iterator(start_val):
if <random check>:
continue # no issues here
# do stuff
这让我感到震惊,因为waaaaay太冗长和复杂。 堆栈溢出中的人有一个更简单的建议吗?
回复评论:
@Glenn Maynard:是的,我驳回了答案。 如果有一种方法可以在一个方法中编写五行,那就太糟糕了......特别是在一直出现的情况下(循环是图灵完成程序的一个共同特征)。
对于寻找具体示例的人:假设我正在使用自定义日期库。 那么我的问题是,你将如何在python中表达这一点:
for (date = start; date < end; date = calendar.next_quarter_end(date)):
if another_calendar.is_holiday(date):
continue
# ... do stuff...
这是我能想到的最好的:
def cfor(first,test,update):
while test(first):
yield first
first = update(first)
def example(blah):
print "do some stuff"
for i in cfor(0,lambda i:i<blah,lambda i:i+1):
print i
print "done"
我希望python有一个闭包表达式的语法。
编辑:另外,请注意,您只需要定义一次cfor(而不是您的complicated_iterator
函数)。
我有点困惑:你有一个复杂的while表达式,一个复杂的下一个表达式,但它们很适合C for循环? 这对我来说没有意义。
我推荐自定义迭代器方法。 您可能会发现迭代器的其他用途,无论如何封装迭代都是很好的做法。
更新:使用您的示例,我肯定会创建一个自定义迭代器。 对我来说,日历能够产生一系列季度日期似乎是很自然的:
class Calendar:
# ...
def quarters(self, start, end):
"""Generate the quarter-start dates between `start` and `end`."""
date = start
while date < end:
yield date
date = self.next_quarter_end(date)
for date in calendar.quarters(start, end):
if another_calendar.is_holiday(date):
continue
# ... do stuff...
这似乎是您的日历类提供的一个很棒的抽象,我打赌你会不止一次地使用它。
关于什么:
date = start
while date < end:
if not another_calendar.is_holiday(date):
# ... do stuff...
date = calendar.next_quarter_end(date)
但是如果你经常使用那个特定的构造,你最好定义一次生成器并像你在问题中那样重新使用它。
(事实是,由于它们是不同的语言,你不可能将C映射中的每个构造都用于Python中更紧凑的构造。它就像声称有一个压缩算法在所有随机输入上同样有效。)
您可以使用try / finally子句来执行更新:
val = START_VAL
while <awkward/complicated test case>:
try:
# do stuff
continue
finally:
val = <awkward/complicated update>
警告:如果你break
这也会执行更新语句。
我经常这样做
while True:
val = <awkward/complicated update>
if not val:
break
etc.
嘿:
def forre(a,i,c,top,increment,run):
increment = increment.replace("++","+=1").replace("--","-=1").replace("; ","")
while i != top:
try: exec(run)
except: print "error: "; print run
try: exec(increment)
except: print "error: "; print increment
forre("int i=",0,"; i<",6,"; i++",
"print i"
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.