2015-10-05 8 views
0

Рассмотрим эти два варианта одной и той же структуры петли:Looping структура лучший подход

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 для цикла настолько сильно отличается от других языков.

В языке, как C для цикла является более или менее синтаксическим сахаром для петли в то время:

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

эквивалентен:

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

В Python она отличается. Его для циклов являются итераторными. Объект итератора инициализируется только один раз, а затем потребляется в последующих итерациях. Следующие фрагменты показывают, что в Python для цикла не является (легко) переводимые в время цикла, а также показывает, что с помощью цикла в то время как забота вашего наставника действует:

>>> 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 
Смежные вопросы