我无法弄清楚这里发生了什么。附加对range
函数的引用有点在索引3
创建递归列表。
>>> x = range(3)
[0, 1, 2]
>>> x.append(x)
[0, 1, 2, [...]]
>>> x[3][3][3][3][0] = 5
[5, 1, 2, [...]]
然而,当我尝试这个时:
>>> x = range(3)
[0, 1, 2]
>>> x.append(range(3))
[0, 1, 2, [0, 1, 2]]
我可以很容易地推断出第二种情况的原因,但却无法理解对range
函数的附加引用对附加列表的影响。
答案 0 :(得分:9)
在python2中,range
是list
s。
list
s,python中的大多数内容都是带有身份的对象。
li = [0,1]
li[1] = li # [0, [...]]
# ^----v
id(li) # 2146307756
id(li[1]) # 2146307756
由于您将列表放在本身中,因此您正在创建递归数据结构。
答案 1 :(得分:0)
首先这很奇怪,你可能不应该在实践中使用它。该问题并非特定于range
函数,而是与引用有关。当您致电x.append(x)
时,您基本上会说x[-1] is x
。因此,当您修改x[0]
时,您还可以修改x[-1][0]
,x[-1][-1][0]
等。
要查看这不是特定范围,您可以使用copy.copy
:
from copy import copy
x = range(1)
x.append(x) # here x[1] is reference to x itself (same object)
print(x[0], x[1][0], x[1][1][0])
x[0] = 1
print(x[0], x[1][0], x[1][1][0]) # all values change
#
x = range(1)
x.append(copy(x)) # x[1] is a copy of x at previous state (new object)
print(x[0], x[1][0]) # cannot call x[1][1][0] -> x[1][1] is an int
x[0] = 1
print(x[0], x[1][0]) # only the first value changes
输出:
(0, 0, 0)
(1, 1, 1)
(0, 0)
(1, 0)