首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在python中模拟C风格的for循环

在python中模拟C风格的for循环
EN

Stack Overflow用户
提问于 2010-04-30 05:30:26
回答 6查看 9.4K关注 0票数 22

(我意识到,即使是这篇文章的标题也会引起轰动)

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...
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 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函数)。

票数 27
EN

Stack Overflow用户

发布于 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类来说,这似乎是一个很好的抽象,我打赌您会不止一次地使用它。

票数 6
EN

Stack Overflow用户

发布于 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中更紧凑的构造。这就像声称拥有一种对所有随机输入都同样有效的压缩算法。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2740901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档