从一个列表的元素创建新列表,引用后者的元素

1 投票
2 回答
4715 浏览
提问于 2025-04-16 22:20

我想从一个已有的列表中创建一个新列表,但不想复制那些元素。结果是这样的:

In [23]: list = range(10)

In [24]: list2 = list[0:4]

In [25]: list
Out[25]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [26]: list2
Out[26]: [0, 1, 2, 3]

虽然这两个列表里的元素看起来有相同的ID,

In [29]: id(list[1])
Out[29]: 145137840

In [30]: id(list2[1])
Out[30]: 145137840

但当我编辑其中一个元素时,我并不是在改变被引用的对象,而是在改变列表中那个位置的值。

In [31]: list[1] = 100

In [32]: id(list[1])
Out[32]: 145138628

In [33]: id(list2[1])
Out[33]: 145137840

In [34]: list
Out[34]: [0, 100, 2, 3, 4, 5, 6, 7, 8, 9]

In [35]: list2
Out[35]: [0, 1, 2, 3]

我想用list2来代表list中的某些特定元素。我在想,应该有一种好的方法来组合一个列表,这样我在改变list的值时,也能编辑list中元素的值。

2 个回答

1

使用可变类型作为列表的元素。例如:

>>> a = [[1], [2]]
>>> b = a[1]
>>> a
[[1], [2]]
>>> b
[2]
>>> b[0]=[3]
>>> a
[[1], [[3]]]
>>> b
[[3]]
>>> 
3

任何时候,只要一个变量里有数字 1 或其他小数字,它们的身份标识(id)总是一样的。这些数字只存在一次,而且它们是不可变的,所以在任何地方引用它们都是安全的。

使用切片语法 [:] 总是会创建一个副本。

当你设置 list1[1] 时,你并不是在改变内存中存储的值,而是把 list1[1] 指向了内存中的一个新位置。所以因为你没有把 list2[1] 指向一个不同的位置,它仍然指向旧的位置和旧的值。

不要把变量命名为 list,因为 Python 里有一个内置的函数叫这个名字。

如果你想在最小修改的情况下实现你说的功能,可以试试:

list1 = [[x] for x in range(10)]
list2 = list1[:4]
list1[1][0] = 100
print list2

你只需要在你想引用的项目后面加上 [0]。因为列表本身不会被替换,只有里面的项目会被替换,而 list2 指向的是列表而不是项目,所以它会保持同步。

撰写回答