2015-10-05 70 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