gdmao002 发表于 2020-9-29 20:25:59

关于列表的相关问题

代码部分
snake_body = [, , , ]
food =
direction = 'right'
if food == snake_body:
    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] += 10
    elif direction == 'right':
      snake_body[-1] -= 10
    print('2:', snake_body)
https://fishc.com.cn/static/image/common/emp.gif
为何倒数第二个数列没做更改去变了
我想要的结果是
[, , , , ]
请问问题出在哪里呢

zltzlt 发表于 2020-9-29 21:07:41

?没看明白你在问什么

疾风怪盗 发表于 2020-9-29 21:10:05

你打印一下内存地址看看,应该和什么存储方式、指向、内存地址之类的有关,就是说你append进的那个最后元素,其实存储的是一个,用的一个内存地址,所以修改也一起修改
我只知道大概时这样,太理论的讲解,要靠版主

snake_body = [, , , ]
food =
direction = 'right'
if food == snake_body:
    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] += 10
    elif direction == 'right':
      snake_body[-1] -= 10
    print('2:', snake_body)
    print(id(snake_body[-1]))
    print(id(snake_body[-2]))
    print(id(snake_body[-3]))

0: [, , , ]
51996360
1: [, , , , ]
51996360
2: [, , , , ]
51996360
51996360
51996200

疾风怪盗 发表于 2020-9-29 21:11:06

zltzlt 发表于 2020-9-29 21:07
?没看明白你在问什么

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

看题目全靠猜啊。。。。。。。。。。

zltzlt 发表于 2020-9-29 21:14:02

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

看题目 ...

{:10_262:}

疾风怪盗 发表于 2020-9-29 21:14:58

zltzlt 发表于 2020-9-29 21:14


应该是内存地址的关系吧,请版主讲课了,这个是什么理论

zltzlt 发表于 2020-9-29 21:15:11

本帖最后由 zltzlt 于 2020-9-29 21:18 编辑

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

解决办法是复制一份副本后再添加进列表:

snake_body = [, , , ]
food =
direction = 'right'
if food == snake_body:
    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] += 10
    elif direction == 'right':
      snake_body[-1] -= 10
    print('2:', snake_body)

zltzlt 发表于 2020-9-29 21:15:25

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

没错

kylin121380 发表于 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]))

gdmao002 发表于 2020-9-30 09:33:07

kylin121380 发表于 2020-9-29 21:15
当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
id(snake_body[-1]) 和 id(snake_b ...

没用过深拷贝,也没有看过这块的内容,但是大致明白了 你们的描述含义,就是相当于修改的内容是 指向该对象的引用 如果是多个 一旦被修改了一个 其他的共同引用的对象值也会跟随一起修改了 类似于C指针对吧 所有指向这块的对象 都被修改了值

gdmao002 发表于 2020-9-30 09:36:15

zltzlt 发表于 2020-9-29 21:15
因为列表的倒数第二个元素和第一个元素指向同一块内存,导致修改了其中一个,另一个也会被修改。

解决办 ...

感谢 指点。 终于明白了为何一个对象的变更会导致其他对象也一起修改,本质是指向的地址是同一个,
那么修改了地址的值,也会导致所以指向这个地址的值都会被改动!
用C语言的指针很好理解!
谢谢大大的帮忙。
可能我描述的不大清晰,让大大头疼了一段时间吧{:5_109:},挺抱歉的!

gdmao002 发表于 2020-9-30 09:41:15

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

嗯。昨天我没找到核心点一直困惑,今天大家都帮忙回答,让我也找到了问题所在,这个是我以前不曾遇到过的
虽然听过深拷贝和浅拷贝,但是以前没看过这块的,直到我自己遇到了无解的问题,然后才明白这些。今天看了你们的解答大致明白了 所谓深和浅的一些大概不同了。
也跟你所说的相同,就是内存地址的问题。
谢谢了哈{:5_109:}

gdmao002 发表于 2020-9-30 09:58:16

kylin121380 发表于 2020-9-29 21:15
当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
id(snake_body[-1]) 和 id(snake_b ...

看来以后进行该类操作的时候 最好是打印下结果。免得又错了哈{:5_109:}
页: [1]
查看完整版本: 关于列表的相关问题