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