簡體   English   中英

在python中模擬C風格的循環

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM