鱼C论坛

 找回密码
 立即注册
查看: 1501|回复: 12

[已解决]关于列表的相关问题

[复制链接]
发表于 2020-9-29 20:25:59 | 显示全部楼层 |阅读模式

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

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

x
代码部分
snake_body = [[280, 340], [270, 340], [260, 340], [250, 340]]
food = [280, 340]
direction = 'right'
if food == snake_body[0]:
    print('0:', snake_body)
    snake_body.append(snake_body[-1])
    print('1:', snake_body)
    if direction == 'up':
        snake_body[-1][-1] += 10
    elif direction == 'down':
        snake_body[-1][-1] -= 10
    elif direction == 'left':
        snake_body[-1][0] += 10
    elif direction == 'right':
        snake_body[-1][0] -= 10
    print('2:', snake_body)

                               
登录/注册后可看大图

为何倒数第二个数列没做更改去变了
我想要的结果是
[[280, 340], [270, 340], [260, 340], [250, 340], [240, 340]]
请问问题出在哪里呢

最佳答案
2020-9-29 21:15:11
本帖最后由 zltzlt 于 2020-9-29 21:18 编辑

因为列表的倒数第二个元素和第一个元素指向同一块内存,导致修改了其中一个,另一个也会被修改。

解决办法是复制一份副本后再添加进列表:
snake_body = [[280, 340], [270, 340], [260, 340], [250, 340]]
food = [280, 340]
direction = 'right'
if food == snake_body[0]:
    print('0:', snake_body)
    snake_body.append(snake_body[-1][:])    # 修改
    print('1:', snake_body)
    if direction == 'up':
        snake_body[-1][-1] += 10
    elif direction == 'down':
        snake_body[-1][-1] -= 10
    elif direction == 'left':
        snake_body[-1][0] += 10
    elif direction == 'right':
        snake_body[-1][0] -= 10
    print('2:', snake_body)
01.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-29 21:07:41 | 显示全部楼层
?没看明白你在问什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:10:05 | 显示全部楼层
你打印一下内存地址看看,应该和什么存储方式、指向、内存地址之类的有关,就是说你append进的那个最后元素,其实存储的是一个,用的一个内存地址,所以修改也一起修改
我只知道大概时这样,太理论的讲解,要靠版主
snake_body = [[280, 340], [270, 340], [260, 340], [250, 340]]
food = [280, 340]
direction = 'right'
if food == snake_body[0]:
    print('0:', snake_body)
    print(id(snake_body[-1]))
    snake_body.append(snake_body[-1])
    print('1:', snake_body)
    print(id(snake_body[-1]))
    if direction == 'up':
        snake_body[-1][-1] += 10
    elif direction == 'down':
        snake_body[-1][-1] -= 10
    elif direction == 'left':
        snake_body[-1][0] += 10
    elif direction == 'right':
        snake_body[-1][0] -= 10
    print('2:', snake_body)
    print(id(snake_body[-1]))
    print(id(snake_body[-2]))
    print(id(snake_body[-3]))

0: [[280, 340], [270, 340], [260, 340], [250, 340]]
51996360
1: [[280, 340], [270, 340], [260, 340], [250, 340], [250, 340]]
51996360
2: [[280, 340], [270, 340], [260, 340], [240, 340], [240, 340]]
51996360
51996360
51996200
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:11:06 | 显示全部楼层
zltzlt 发表于 2020-9-29 21:07
?没看明白你在问什么


楼主问的是,最后一行最后两个元素,为什么一起被修改了,代码里他就写了修改最后一个元素值

看题目全靠猜啊。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:14:02 | 显示全部楼层
疾风怪盗 发表于 2020-9-29 21:11
楼主问的是,最后一行最后两个元素,为什么一起被修改了,代码里他就写了修改最后一个元素值

看题目 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:14:58 | 显示全部楼层

应该是内存地址的关系吧,请版主讲课了,这个是什么理论
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:15:11 | 显示全部楼层    本楼为最佳答案   
本帖最后由 zltzlt 于 2020-9-29 21:18 编辑

因为列表的倒数第二个元素和第一个元素指向同一块内存,导致修改了其中一个,另一个也会被修改。

解决办法是复制一份副本后再添加进列表:
snake_body = [[280, 340], [270, 340], [260, 340], [250, 340]]
food = [280, 340]
direction = 'right'
if food == snake_body[0]:
    print('0:', snake_body)
    snake_body.append(snake_body[-1][:])    # 修改
    print('1:', snake_body)
    if direction == 'up':
        snake_body[-1][-1] += 10
    elif direction == 'down':
        snake_body[-1][-1] -= 10
    elif direction == 'left':
        snake_body[-1][0] += 10
    elif direction == 'right':
        snake_body[-1][0] -= 10
    print('2:', snake_body)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:15:25 | 显示全部楼层
疾风怪盗 发表于 2020-9-29 21:14
应该是内存地址的关系吧,请版主讲课了,这个是什么理论

没错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-29 21:15:44 | 显示全部楼层
本帖最后由 kylin121380 于 2020-9-29 21:19 编辑

当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
id(snake_body[-1]) 和 id(snake_body[-2])是相同的,可以采用深拷贝
import copy

snake_body.append(copy.deepcopy(snake_body[-1]))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-30 09:33:07 | 显示全部楼层
kylin121380 发表于 2020-9-29 21:15
当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
id(snake_body[-1]) 和 id(snake_b ...

没用过深拷贝,也没有看过这块的内容,但是大致明白了 你们的描述含义,就是相当于修改的内容是 指向该对象的引用 如果是多个 一旦被修改了一个 其他的共同引用的对象值也会跟随一起修改了 类似于C指针对吧 所有指向这块的对象 都被修改了值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-30 09:36:15 | 显示全部楼层
zltzlt 发表于 2020-9-29 21:15
因为列表的倒数第二个元素和第一个元素指向同一块内存,导致修改了其中一个,另一个也会被修改。

解决办 ...

感谢 指点。 终于明白了为何一个对象的变更会导致其他对象也一起修改,本质是指向的地址是同一个,
那么修改了地址的值,也会导致所以指向这个地址的值都会被改动!
用C语言的指针很好理解!
谢谢大大的帮忙。
可能我描述的不大清晰,让大大头疼了一段时间吧,挺抱歉的!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-30 09:41:15 | 显示全部楼层
疾风怪盗 发表于 2020-9-29 21:10
你打印一下内存地址看看,应该和什么存储方式、指向、内存地址之类的有关,就是说你append进的那个最后元素 ...

嗯。昨天我没找到核心点一直困惑,今天大家都帮忙回答,让我也找到了问题所在,这个是我以前不曾遇到过的
虽然听过深拷贝和浅拷贝,但是以前没看过这块的,直到我自己遇到了无解的问题,然后才明白这些。今天看了你们的解答大致明白了 所谓深和浅的一些大概不同了。
也跟你所说的相同,就是内存地址的问题。
谢谢了哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-30 09:58:16 | 显示全部楼层
kylin121380 发表于 2020-9-29 21:15
当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
id(snake_body[-1]) 和 id(snake_b ...

看来以后进行该类操作的时候 最好是打印下结果。免得又错了哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-18 11:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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