2010-05-31 61 views
11

因此,在Python(雖然我認爲它可以適用於很多語言),我發現自己有這樣的事情經常:小的代碼冗餘(沒有感覺乾淨)

the_input = raw_input("what to print?\n") 
while the_input != "quit": 
    print the_input 
    the_input = raw_input("what to print?\n") 

也許我太挑剔了,但我不喜歡the_input = raw_input("what to print?\n")必須重複的行。它降低了可維護性和組織性。但是我沒有看到避免重複代碼而沒有進一步惡化問題的任何解決方法。在某些語言中,我可以寫這樣的事:

while ((the_input=raw_input("what to print?\n")) != "quit") { 
    print the_input 
} 

這絕對是符合Python和Python甚至不容許據我所知循環條件範圍內分配。

這有效修復代碼冗餘,

while 1: 
    the_input = raw_input("what to print?\n") 
    if the_input == "quit": 
     break 
    print the_input 

但感覺並不完全正確要麼。 while 1意味着這個循環將永遠運行;我正在使用一個循環,但給它一個假的條件,並將其放入其中。

我是不是太挑剔?有一個更好的方法嗎?也許有一些我不知道的爲此設計的語言結構?

+1

我認爲第一種形式是完全可以接受的。 – 2010-05-31 03:52:33

+5

這是一種常見的模式,稱爲[循環半](http://www.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half)。 – 2010-05-31 03:58:14

回答

30

想想迭代器 - 例如,在這種特殊情況下:

for the_input in iter(lambda: raw_input('what to print?\n'), 'quit'): 
    print the_input 

多數循環Python中,除了在抽象的非常最低水平,最好爲for環路一些下屬的幫助下實現的迭代器捕獲「循環邏輯」 - iter內置可以幫助(如這裏),有時genexps(生成器表達式)可以,有時標準庫模塊itertools來救援。

大多數情況下你會選擇編寫自定義發生器功能(使用yield的),或更偶爾(當你真的需要複雜的狀態管理)的自定義iterator類(一個定義__iter__特殊方法return self,和next [或__next__在Python]的最新版本]返回從迭代「的下一個值)。

無論從任何除了捕捉循環邏輯是,你上依次產生的各種項目做循環itse如果是這裏的關鍵抽象幫手!

+4

這感覺有點太聰明瞭...... – 2010-05-31 03:51:34

+0

+1:爲迭代選擇'for'循環。用任何提供它們的語言。 – Johnsyweb 2010-05-31 03:52:53

+0

這是一個了不起的解決方案。所以不會讓我接受另一個4分鐘的答案;-) – Ponkadoodle 2010-05-31 03:58:05