2015-10-05 28 views
0

考慮同樣的循環結構,這兩個變種:循環結構最好的辦法

x = find_number_of_iterations() 
for n in range(x): 
    # do something in loop 

和:

for n in range(find_number_of_iterations()): 
    # do something 

將在第二循環評估每個後續循環運行的方法find_number_of_iterations,還是會方法find_number_of_iterations即使在第二個變體中也只能評估一次?

+2

你可以很容易地這個測試自己,而是:無論是方式,該功能只被調用一次。 – jonrsharpe

+0

我該如何測試這個。我的導師批評我的代碼在第二個變體中,因爲他說它會在每個循環運行中評估 – oat

+3

然後,你會告訴你的導師他們錯了!你可以通過傳遞一個函數來測試它,該函數記錄被調用的次數爲find_number_of_iterations,然後檢查是否爲1。 – jonrsharpe

回答

1

我懷疑你的導師的混亂可追溯到一個事實,即Python的for循環的語義是如此比在其他語言非常不同。

在像C語言的for循環是或多或少語法糖while循環:

for(i = 0; i < n; i++) 
{ 
    //do stuff 
} 

相當於:

i = 0; 
while(i < n) 
{ 
    //do stuff 
    i++ 
} 

在Python它是不同的。它的for循環是基於迭代器的。迭代器對象只進行一次初始化,然後在後續迭代中使用。下面的代碼展示了Python的for循環是不(容易)翻譯成一個while循環,並且也表明while循環您的導師的關注是有效的:

>>> def find_number_of_iterations(): 
    print("called") 
    return 3 

>>> for i in range(find_number_of_iterations()): print(i) 

called 
0 
1 
2 

>>> i = 0 
>>> while i < find_number_of_iterations(): 
    print(i) 
    i += 1 


called 
0 
called 
1 
called 
2 
called 
1

無論哪種方式,該功能只被調用一次。您可以證明這一點,如下所示:

>>> def test_func(): 
    """Function to count calls and return integers.""" 
    test_func.called += 1 
    return 3 

# first version 
>>> test_func.called = 0 
>>> x = test_func() 
>>> for _ in range(x): 
    print 'loop' 


loop 
loop 
loop 
>>> test_func.called 
1 

# second version 
>>> test_func.called = 0 
>>> 
>>> for _ in range(test_func()): 
    print 'loop' 


loop 
loop 
loop 
>>> test_func.called 
1 

該函數被調用一次,調用該函數傳遞給range(當時叫range的結果遍歷)的結果;這兩個版本在邏輯上是等效的。

1

函數被調用一次。從邏輯上講,是否每次迭代都要調用它,然後循環範圍可能發生變化,從而導致各種嚴重破壞。這很容易測試:

def find_iterations(): 
    print "find_iterations called" 
    return 5 

for n in range(find_iterations()): 
    print n 

結果:

$ python test.py 
find_iterations called 
0 
1 
2 
3 
4