鱼C论坛

 找回密码
 立即注册
查看: 2256|回复: 8

[已解决]赋值 VS 分片拷贝

[复制链接]
发表于 2023-4-28 13:18:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 lzb1001 于 2023-5-4 11:19 编辑

小甲鱼教材和视频举例:
>>> list1 = [1, 3, 2, 9, 7, 8] # list1是原列表
>>> list2 = list1[:] # list2是使用分片方式得到的拷贝
>>> list2
[1, 3, 2, 9, 7, 8]
>>> list3 = list1 # list3是使用赋值方式得到的结果
>>> list3
[1, 3, 2, 9, 7, 8]

上面list1、list2、list3看起来好像一样,利用列表sort()方法做下排序修改后再来对比看看:

>>> list1.sort()
>>> list1
[1, 2, 3, 7, 8, 9] # 原列表list1已按从小到大顺序排列!
>>> list2
[1, 3, 2, 9, 7, 8] # 使用分片方式得到的拷贝list2保持不变!
>>> list3
[1, 2, 3, 7, 8, 9] # 使用赋值方式得到的结果list3会跟着变!




课后习题:
1.>>> old = [1, 2, 3, 4, 5]
2.>>> new = old
3.>>> old = [6]
4.>>> print(new)

按小甲鱼小甲鱼教材和视频举例,使用赋值方式获得的结果会随着一起发生改变,所以我的答案是[6]

没想到答案竟然是[1, 2, 3, 4, 5]

请大神讲解。

最佳答案
2023-4-28 23:37:54
lzb1001 发表于 2023-4-28 23:24
……并没有修改`old`所指向的列表,而是让`old`指向了一个全新的列表。……

这句话本身就有些拗口或 ...

抱歉,我将尝试以更简单的方式解释这个问题。

首先,当我们在Python中创建一个列表并将其赋值给一个变量时,例如 old = [1, 2, 3, 4, 5] ,这个变量 old 实际上是一个指向列表的引用(或者说指针),而不是列表本身。

当我们使用 new = old 时,我们让 new 变量也指向了 old 所指向的那个列表。现在, old 和 new 都指向同一个列表。

接下来,当我们创建一个新的列表 old = [6] 时,我们实际上是创建了一个全新的列表,并让 old 指向这个新列表。这个操作并没有改变原来的列表(即 [1, 2, 3, 4, 5] ),而只是改变了 old 的指向。 new 仍然指向原来的那个列表,即 [1, 2, 3, 4, 5] 。

所以,当我们打印 new 时,输出的结果是 [1, 2, 3, 4, 5] 。这是因为我们并没有修改 old 原来指向的列表,而只是让 old 指向了一个全新的列表。希望这次解释更容易理解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-28 13:26:26 | 显示全部楼层
当你使用赋值语句`new = old`时,你实际上是让`new`指向了`old`所指向的那个列表,此时它们指向同一个列表。但是在第三行`old = [6]`时,你创建了一个新的列表`[6]`,并让`old`指向这个新列表。这个过程并没有改变`new`指向的列表,因此`new`仍然指向原来的`[1, 2, 3, 4, 5]`列表。

为了更清楚地解释这个问题,我们可以使用下面的步骤来理解:

1. 创建列表`old = [1, 2, 3, 4, 5]`,此时`old`指向这个列表。
2. 使用赋值语句`new = old`,让`new`也指向这个列表。现在,`old`和`new`都指向同一个列表`[1, 2, 3, 4, 5]`。
3. 创建一个新的列表`old = [6]`,让`old`指向这个新列表。这时候,`new`仍然指向原来的那个列表`[1, 2, 3, 4, 5]`。
4. 打印`new`,输出结果是`[1, 2, 3, 4, 5]`。

请注意,在这个例子中,我们并没有修改`old`所指向的列表,而是让`old`指向了一个全新的列表。这就是为什么`new`的值没有随之改变的原因。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-28 13:38:25 | 显示全部楼层
old 指向一个位置(假设他是a),a存了[1,2,3,4,5]
new 表示old,old指向a,所以new是[1,2,3,4,5]
old变成c,c是[6]
new还是a

至于为什么有时候会变:
old=[1,2,3,4,5]
new=old
old[:]=[6]
#new是6
old是d,d是[1,2,3,4,5]
new是old,old是d
d的全部数据,变成[6]
new也变[6]了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-28 23:24:40 | 显示全部楼层
本帖最后由 lzb1001 于 2023-4-28 23:28 编辑
isdkz 发表于 2023-4-28 13:26
当你使用赋值语句`new = old`时,你实际上是让`new`指向了`old`所指向的那个列表,此时它们指向同一个列表 ...


……并没有修改`old`所指向的列表,而是让`old`指向了一个全新的列表。……

这句话本身就有些拗口或不好理解……

是不是说:

old只是原来列表a的其中一个标签,现在让`old`指向了一个全新的列表b,也就是给全新的列表b一个叫old标签,而原来的列表a并没有发生改变,只是少了一个叫old的标签,new标签还在。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-28 23:37:54 | 显示全部楼层    本楼为最佳答案   
lzb1001 发表于 2023-4-28 23:24
……并没有修改`old`所指向的列表,而是让`old`指向了一个全新的列表。……

这句话本身就有些拗口或 ...

抱歉,我将尝试以更简单的方式解释这个问题。

首先,当我们在Python中创建一个列表并将其赋值给一个变量时,例如 old = [1, 2, 3, 4, 5] ,这个变量 old 实际上是一个指向列表的引用(或者说指针),而不是列表本身。

当我们使用 new = old 时,我们让 new 变量也指向了 old 所指向的那个列表。现在, old 和 new 都指向同一个列表。

接下来,当我们创建一个新的列表 old = [6] 时,我们实际上是创建了一个全新的列表,并让 old 指向这个新列表。这个操作并没有改变原来的列表(即 [1, 2, 3, 4, 5] ),而只是改变了 old 的指向。 new 仍然指向原来的那个列表,即 [1, 2, 3, 4, 5] 。

所以,当我们打印 new 时,输出的结果是 [1, 2, 3, 4, 5] 。这是因为我们并没有修改 old 原来指向的列表,而只是让 old 指向了一个全新的列表。希望这次解释更容易理解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-28 23:53:08 | 显示全部楼层
本帖最后由 lzb1001 于 2023-4-28 23:56 编辑
isdkz 发表于 2023-4-28 23:37
抱歉,我将尝试以更简单的方式解释这个问题。

首先,当我们在Python中创建一个列表并将其赋值给一个变 ...


我将大神第一次的回答修改完善了下,看下对不对?

变量名更像是变量的标签,一个变量可能也可以有N个标签(也就是变量名)

为了更清楚地解释这个问题,我们可以使用下面的步骤来理解:

1、首先,创建列表`old = [1, 2, 3, 4, 5]`,此时`old`指向列表[1, 2, 3, 4, 5],old是这个列表目前唯一的标签

2. 接着,使用赋值语句`new = old`,让`new`也指向列表[1, 2, 3, 4, 5],new也成为这个列表的标签之一,现在`old`和`new`都指向同一个列表`[1, 2, 3, 4, 5]`,都是这个列表的标签。

3. 然后,创建一个新的列表`old = [6]`,让`old`指向这个新列表[6],old成为这个新列表目前唯一的标签,同时old也不再是原来列表[1, 2, 3, 4, 5]的标签之一。注意:这时候`new`成为原来列表[1, 2, 3, 4, 5]目前唯一的标签,它仍然指向原来列表`[1, 2, 3, 4, 5]`。

4. 最后,打印`new`,输出结果是`[1, 2, 3, 4, 5]`。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-29 00:00:15 | 显示全部楼层
lzb1001 发表于 2023-4-28 23:53
我将大神第一次的回答修改完善了下,看下对不对?

变量名更像是变量的标签,一个变量可能也可以有N ...

是的,你的解释是正确的。将变量名视为变量的标签可以更好地理解Python中变量和引用的关系。在这个例子中,你详细解释了 old 和 new 是如何指向不同列表的,并且在执行 old = [6] 操作后, new 仍然指向原来的列表 [1, 2, 3, 4, 5] 。这样解释更容易理解,很好!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-29 00:05:25 | 显示全部楼层
歌者文明清理员 发表于 2023-4-28 13:38
old 指向一个位置(假设他是a),a存了[1,2,3,4,5]
new 表示old,old指向a,所以new是[1,2,3,4,5]
old变 ...

好神奇

仅仅在old后面添加了一个[:]而已

new返回的结果就变成6了

不过搞得更晕了……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-29 11:26:52 | 显示全部楼层

在第2行,变量new被赋值为old,这意味着它们指向同一个列表对象,即它们引用相同的内存地址。在第3行,old被重新赋值为[6],这不会改变new的值,因为new仍然指向原始的列表对象。因此,print(new)将输出原始列表的内容,即[1, 2, 3, 4, 5]。

和视频举例中的不同之处在于,在视频中,原列表并没有被重新赋值,而是直接修改了列表元素的值。因此,new和old都引用了同一个列表对象,它们在内存中引用相同的内存地址。这意味着任何对列表的修改都会影响到new和old,因为它们都指向相同的列表对象。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 11:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表