Понимание списка, который использует рекурсию

Мы можем вычислить пересечение минус объединение списков:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two', 'Five']

set(temp1+temp2)-(set(temp1)&set(temp2))

Out: set(['Four', 'Five', 'Three']) 
1
задан jferard 24 March 2019 в 08:32
поделиться

1 ответ

Цикл 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

Понимание списка в основном:

    [ 1123] применяет 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 для каждого [ 1114]

Следовательно, задания дают: ans = sort(ans[0], i+1), затем ans = sort(ans[1], i+1), ..., ans = sort(ans[-1], i+1) где ans[-1] - последний элемент оригинала ans 2 . [+1136]

Эквивалентный цикл вашего понимания списка:

>>> 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 все еще имеет ссылку в исходном списке.

Было бы иначе, если вы измените список изнутри тела цикла ( настоятельно не рекомендуется ):

>>> 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
0
ответ дан jferard 24 March 2019 в 08:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: