了解使用递归的列表理解

时间:2019-03-21 04:11:16

标签: recursion list-comprehension

我目前正在学习有关列表理解的知识,并遇到了以下递归代码行:

when(someMock.someMethod()).thenCallRealMethod();

我尝试用以下内容替换该行:

ans = [sort(a, i + 1) for a in ans]

有人可以帮我弄清楚我哪里做错了吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

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的最后一个元素< sup> 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。 / p>

[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