
把代码精简了一下

我本以为输出结果会是个[[],[]],输出结果是个列表嵌套了两个列表,每个列表里又嵌套了 2 个列表...

猜测是个递归,debug 一下确实是这样的

有几个问题:
1 、这个为啥是个递归?
2 、这个递归为什么没有爆栈?
3 、修改了一下代码,为什么返回了(True, True)?

1 chaosgoo Mar 4, 2021 1.root 里面放了两个 root 的引用 2.root 里面只是存了两个地址而已 3.自己和自己比较当然是 True |
2 THESDZ Mar 4, 2021 实参,形参 |
4 aijam Mar 4, 2021 相当于: root = [] root.append(root) root.append(root) |
5 vicalloy Mar 4, 2021 同楼上,就是一个递推的引用,换成 dict 是不是就好理解多了。 >>> o = {} >>> o['o'] = o >>> o {'o': {...}} |
6 Vegetable Mar 4, 2021 Circular reference detected 给你化简一下吧 root = [] root.append(root) |
7 aijam Mar 4, 2021 先理解下面什么意思,也就好理解了 root = [] root.append(root) |
8 nznd Mar 4, 2021 >>> root=[] >>> id(root) 2296081934592 >>> id(root[:]) 2296081935040 >>> root[:]=[root,root] >>> id(root) 2296081934592 >>> id(root[:]) 2296081935040 >>> id(root[0]) 2296081934592 >>> id(root[1]) 2296081934592 简单来说 就是 root[0] 和 root[1] 都指向了 root,root[:]是 root 的一个指针(类似的概念 忘了叫啥了,刷 leetcode 可以用这个装作是原地算法(直接改这个值 |
9 acmore Mar 4, 2021 魔法就是自指广义表: root = [] root.append(root) 另外基本上所有语言都可以这么玩,不只是 Python |
10 RockShake Mar 4, 2021 自己引用了自己,死循环,print 无法打印出所有 |
11 SystemLight Mar 4, 2021 root[:]=[1,2]和 root=[1,2]两种写法有啥区别 |
12 karloku Mar 4, 2021 1. 上面都回答了 2. 爆栈对应于堆栈. 变量引用不会建立堆栈, 自然没有爆栈问题. 如果你准备用递归的函数来深层处理这个变量, 每次函数调用都会建立堆栈, 那基本就要爆了. |
13 karatsuba Mar 4, 2021 这个不限于[], 即 root=[1], root=root.append(root),也会是[1, [...]] |
14 Jirajine Mar 4, 2021 via Android 一切皆对象(的引用) 因而所有变量都是引用类型(值类型可以看作是一种 inline 优化,因而可以看作引用类型) |
15 lizytalk Mar 4, 2021 你想说 root[0] == root 和 root[0] is root 都是 True ? root=root 和 root is root 是 True 没什么可说的吧 |
16 dayeye2006199 Mar 5, 2021 这个写法有什么实际用途吗?想学习一下魔法 |
17 SjwNo1 Mar 5, 2021 可变类型 地址引用 |
18 no1xsyzy Mar 5, 2021 |
19 cassidyhere Mar 5, 2021 标准库 functools.lru_cache 把它当双向链表用 摘部分代码: PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields root = [] # root of the circular doubly linked list root[:] = [root, root, None, None] # initialize by pointing to self # Use the old root to store the new key and result. oldroot = root oldroot[KEY] = key oldroot[RESULT] = result # Empty the oldest link and make it the new root. # Keep a reference to the old key and old result to # prevent their ref counts from going to zero during the # update. That will prevent potentially arbitrary object # clean-up code (i.e. __del__) from running while we're # still adjusting the links. root = oldroot[NEXT] oldkey = root[KEY] oldresult = root[RESULT] root[KEY] = root[RESULT] = None |
20 lithbitren Mar 6, 2021 只要引用名归零或者作用域销毁,循环引用也是可以被 GC 的 |