Цикл for и понимание списка не эквивалентны.
Представьте, что у нас есть:
>>> def sort(a, _): return 2*a
...
>>> i=0
Тогда:
>>> ans=list(range(5))
>>> ans = [sort(a, i + 1) for a in ans]
>>> ans
[0, 2, 4, 6, 8]
Но:
>>> ans=list(range(5))
>>> for a in ans: ans=(sort(a, i+1))
>>> ans
8
Понимание списка в основном:
- применяет
sort(a, i+1)
к каждому a
в ans
- , затем присваивает результат самой переменной
ans
.
Как сказал @chepner в комментарии, здесь нет рекурсии [1] .Это эквивалентно:
>>> ans=list(range(5))
>>> new_ans = [sort(a, i + 1) for a in ans]
>>> ans = new_ans
>>> new_ans
[0, 2, 4, 6, 8]
В то время как цикл for:
- перебирает
ans
: - назначает
sort(a, i+1)
для ans
для каждого a
Следовательно, назначения дают: ans = sort(ans[0], i+1)
, затем ans = sort(ans[1], i+1)
, ..., ans = sort(ans[-1], i+1)
, где ans[-1]
- последний элемент оригинала ans
2 .
Эквивалент цикла вашего понимания списка:
>>> ans=list(range(5))
>>> new_ans=[]
>>> for a in ans: new_ans.append(sort(a, i+1))
>>> ans = new_ans # assignement here
>>> ans
[0, 2, 4, 6, 8]
[1] Функция может использовать рекурсию, но я 'я не уверен, что рекурсия будет означать для понимания списка, если вы не используете грязный хак: для записи https://stackoverflow.com/a/221874/6914441.
[2] Обратите внимание, что переназначение переменной ans
делаетне изменять исходный список:
- при запуске цикла Python создает итератор над списком и сохраняет ссылку в списке;
- при повторном воздействии на
ans
Цикл for по-прежнему содержит ссылку на исходный список.
Было бы иначе, если бы вы изменили список из тела цикла ( stronglу обескуражен ):
>>> xs=list(range(5))
>>> for x in xs: print(x, xs);_=xs.pop(0)
...
0 [0, 1, 2, 3, 4]
2 [1, 2, 3, 4]
4 [2, 3, 4]
Мы удаляем первый элемент для каждой итерации, но индекс продолжает расти:
[*0*, 1, 2, 3, 4] # then pop 0
[1, *2*, 3, 4] # then pop 1
[2, 3, *4*] # then pop 2