python,简单的for循环疑问

下面两个代码的区别在于zh_yundong = {"怪物类型": "普通", "血量": 1000}是否在 for cishu in range(7)之下
但是输出的结果却不一样,第一段代码的输出结果是我想要的,即前3个怪物是精英,后面的怪物是普通怪物。但是第二段代码的结果却是全部都变成了精英怪物,这是为什么?


guaiwu = []
#先制造一个总的怪物关系,之后更改怪物信息再用切片修改
for cishu in range(7):
    zh_yundong = {"怪物类型": "普通", "血量": 1000}
    guaiwu.append(zh_yundong)
print(guaiwu)
#此时我们想将一部分怪物信息变化
for guaiwu_2 in guaiwu[:3]:
    if guaiwu_2["怪物类型"] == "普通":
        guaiwu_2["怪物类型"] = "精英"
        guaiwu_2["血量"] = 2000
        print("本次实验成功")
print(guaiwu)

guaiwu = []
#先制造一个总的怪物关系,之后更改怪物信息再用切片修改
zh_yundong = {"怪物类型": "普通", "血量": 1000}
for cishu in range(7):
    guaiwu.append(zh_yundong)
print(guaiwu)
#此时我们想将一部分怪物信息变化
for guaiwu_2 in guaiwu[:3]:
    if guaiwu_2["怪物类型"] == "普通":
        guaiwu_2["怪物类型"] = "精英"
        guaiwu_2["血量"] = 2000
        print("本次实验成功")
print(guaiwu)

第二种写法,guaiwu中append添加的都是相同的对象zh_yundong,所以后面修改谁都是一样的
第一个是在append前,都重新定义的zh_yundong,所以这些对象是不一样的

应该是 直接使用append方法将字典添加到列表中,如果需要更改字典中的数据,那么列表中的内容也会发生改变,这是因为dict在Python里是object,不属于primitive type(即int、float、string、None、bool)。这意味着你一般操控的是一个指向object(对象)的指针,而非object本身。(引用自下面的参考链接)


在第二份代码里面,怪物列表guaiwu不断往列表添加了7份zh_yundong字典的引用地址,所以他的七份项目都是指向zh_yundong这个字典,所以在第二个for循环只进行一次判断后,修改了列表guaiwu第一个项目的内容为精英类型怪物后,后面所有的内容页同步修改了,然后如此重复循环修改三次后,怪物列表guaiwu后面的数据也同步为前面修改的精英怪,所以第二份代码里怪物列表所有的怪物都修改为精英怪了。


而第一份代码是添加的七份不同引用地址的字典,所以他们判断完前三项,然后修改其为精英数据,列表怪物还是普通怪。


可以在第二个for循环修改前三项怪物为精英怪的if判断那里加一句打印语句:print("guaiwu_2",guaiwu_2),会发现即只打印了一次,说明经过一次判断的替换修改,前三项的怪物已经修改为精英怪,所以后面两次判断才会if条件不满足,才会导致只打印一次,测试代码如下:
参考链接:
Python——列表中append存放字典遇到的问题_pfm685757的博客-CSDN博客_append可以用于字典吗
Python 列表 append()函数使用详解_士别三日wyx的博客-CSDN博客_python中append

 
guaiwu = []
#先制造一个总的怪物关系,之后更改怪物信息再用切片修改
zh_yundong = {"怪物类型": "普通", "血量": 1000}
for cishu in range(7):
    guaiwu.append(zh_yundong)
print(guaiwu)
print("len(guaiwu)=",len(guaiwu))
#此时我们想将一部分怪物信息变化
print("guaiwu[:3]=",guaiwu[:3])
for guaiwu_2 in guaiwu[:3]:
    if guaiwu_2["怪物类型"] == "普通":
        print("guaiwu_2",guaiwu_2) #观察修改几次
        guaiwu_2["怪物类型"] = "精英"
        guaiwu_2["血量"] = 2000
        print("本次实验成功")
print(guaiwu)

img