(我意识到,即使是这篇文章的标题也会引起轰动)
Python做出了深思熟虑的设计选择,让for
循环使用显式的可迭代代码,并在大多数情况下大大简化了代码。
然而,如果你的测试用例和更新函数很复杂,有时构造一个迭代器是相当痛苦的,所以我发现我自己编写了以下while循环:
val = START_VAL
while <awkward/complicated test case>:
# do stuff
...
val = <awkward/complicated update>
这样做的问题是更新位于while
块的底部,这意味着如果我想在其中嵌入一个continue
,我必须:
我可以走手工滚动复杂迭代器的路线:
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
这让我觉得太冗长和复杂了。堆栈溢出的人有没有更简单的建议?
回复评论:
@Glenn Maynard:是的,我驳斥了这个答案。如果有一种方法可以在一行中完成,那么写五行代码是不好的。特别是在经常出现的情况下(循环是Turing-complete程序的一个常见特性)。
对于正在寻找具体示例的人们:假设我正在使用一个自定义日期库。我的问题是,您如何在python中表达这一点:
for (date = start; date < end; date = calendar.next_quarter_end(date)):
if another_calendar.is_holiday(date):
continue
# ... do stuff...
发布于 2010-04-30 10:21:14
这是我能想到的最好的:
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
函数)。
发布于 2010-04-30 05:41:31
我有点困惑:你有一个复杂的while表达式和一个复杂的next表达式,但它们都很适合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...
对于您的calendar类来说,这似乎是一个很好的抽象,我打赌您会不止一次地使用它。
发布于 2010-04-30 11:04:12
下面是什么:
date = start
while date < end:
if not another_calendar.is_holiday(date):
# ... do stuff...
date = calendar.next_quarter_end(date)
但是,如果您经常使用这个特定的结构,那么您最好定义一次生成器,然后像您在问题中所做的那样重用它。
(事实是,由于它们是不同的语言,您不可能将C中的每个构造都映射到Python中更紧凑的构造。这就像声称拥有一种对所有随机输入都同样有效的压缩算法。)
https://stackoverflow.com/questions/2740901
复制相似问题