append 后如何删除_for 循环遍历与容器对象、可变对象、append方法的结合例题

关于容器对象、可变对象、append方法、for循环遍历的结合:

例题:将字典person的id循环遍历3次后,加入列表team中,再在列表team中加入name值。[1]

第一种代码:

person = {'name': '', 'id': 0}
team = []

for i in range(3):
    x = person
    x['id'] = i
    team.append(x)

team[0]['name'] = 'Jack'
team[1]['name'] = 'Pony'
team[2]['name'] = 'Crossion'

print(team)

输出结果:

b4ea706125fd95c477fc887974b94c1d.png

结果,并不是想象中,包含id=0,name=Jack,id=1,name=Pony等的对应值的列表。

为了便于查看问题,在过程代码中,重新补充了print输出,

演示:

person = {'name': '', 'id': 0}
team = []

for i in range(3):
    x = person
    x['id'] = i
    print('person =',person,'nteam =',team)
    team.append(x)
    print('person =',person,'nteam =',team)
    print('-'*10)


team[0]['name'] = 'Jack'
print('person =',person,'nteam =',team)
print('-'*10)

team[1]['name'] = 'Pony'
print('person =',person,'nteam =',team)
print('-'*10)

team[2]['name'] = 'Crossin'
print('person =',person,'nteam =',team)
print('-'*10)

输出显示

5e5ebf33acf33a202b809d6273f8c742.png

原因:

容器对象person字典,变量 x 引用可变的容器对象person字典,且for遍历id,每一次都在person字典原地进行修改。

team列表append方法,每一次增加的变量x,都引用同一个可变容器对象person。

每当for循环一次,字典person的id被修改,作为容器对象的字典person 原地修改后(内存地址不变),

由于列表team内增加的每一个元素,都同时引用字典person,于是元素都同时改变。

原理图

5101fbd778c1b55095baaac450f0f40b.png
http://dwz.date/dA3u
http://www.pythontutor.com/visualize.html#code=person%20%3D%20%7B'name'%3A%20'',%20'id'%3A%200%7D%0Ateam%20%3D%20%5B%5D%0A%0Afor%20i%20in%20range%283%29%3A%0A%20%20%20%20x%20%3D%20person%0A%20%20%20%20x%5B'id'%5D%20%3D%20i%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20team.append%28x%29%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20print%28'-'*10%29%0A%0A%0Ateam%5B0%5D%5B'name'%5D%20%3D%20'Jack'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B1%5D%5B'name'%5D%20%3D%20'Pony'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B2%5D%5B'name'%5D%20%3D%20'Crossin'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29&cumulative=true&curInstr=33&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false

第二种代码:

删除变量 x ,for循环直接遍历字典person的id,代码如下:

person = {'name': '', 'id': 0}
team = []

for i in range(3):
    person['id'] = i
    team.append(person)

team[0]['name'] = 'Jack'
team[1]['name'] = 'Pony'
team[2]['name'] = 'Crossion'

print(team)

输出依然是:

67df51849ea68f8f725f0e9c96971592.png

演示:

person = {'name': '', 'id': 0}
team = []

for i in range(3):
    person['id'] = i
    print('person =',person,'nteam =',team)
    team.append(person)
    print('person =',person,'nteam =',team)
    print('-'*10)


team[0]['name'] = 'Jack'
print('person =',person,'nteam =',team)
print('-'*10)

team[1]['name'] = 'Pony'
print('person =',person,'nteam =',team)
print('-'*10)

team[2]['name'] = 'Crossin'
print('person =',person,'nteam =',team)
print('-'*10)

输出:

e514d6365445b8b43cbd45ceea1d181c.png

问题存在:

即使没有了变量x,在for循环每次遍历id后,每当id修改一次,person就在原地修改一次,列表team中append追加的元素,依然都指向同一个容器对象字典person内

09e1e78e28808c6ff302d5af9c30c896.png
http://dwz.date/dA3F
http://www.pythontutor.com/visualize.html#code=person%20%3D%20%7B'name'%3A%20'',%20'id'%3A%200%7D%0Ateam%20%3D%20%5B%5D%0A%0Afor%20i%20in%20range%283%29%3A%0A%20%20%20%20person%5B'id'%5D%20%3D%20i%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20team.append%28person%29%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20print%28'-'*10%29%0A%0A%0Ateam%5B0%5D%5B'name'%5D%20%3D%20'Jack'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B1%5D%5B'name'%5D%20%3D%20'Pony'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B2%5D%5B'name'%5D%20%3D%20'Crossin'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A&cumulative=false&curInstr=19&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false

如何让for每一次遍历id时,在不同的person字典呢?

for 循环遍历id时,要顺便生成不同的person内存地址。

第三种代码:

team = []
for i in range(3):
    person = {'name': '', 'id': 0}
    person['id'] = i
    team.append(person)


team[0]['name'] = 'Jack'
team[1]['name'] = 'Pony'
team[2]['name'] = 'Crossin'
print(team)

输出:

daf2c94da0240b6d7bf6bf513187ca1d.png

演示代码:

team = []
for i in range(3):
    person = {'name': '', 'id': 0}
    person['id'] = i
    print('person =',person,'nteam =',team)
    team.append(person)
    print('person =',person,'nteam =',team)
    print('-'*10)


team[0]['name'] = 'Jack'
print('person =',person,'nteam =',team)
print('-'*10)

team[1]['name'] = 'Pony'
print('person =',person,'nteam =',team)
print('-'*10)

team[2]['name'] = 'Crossin'
print('person =',person,'nteam =',team)
print('-'*10)

输出:

d2e231586cd9d0547793d25d8f9305d9.png

person在for循环中,每一次for开始遍历时,都会初始化字典person,

for i in range(3):
    person = {'name': '', 'id': 0}

创建一个新的对象,id遍历后,所在的不同的字典person,不再是原地修改person,所以列表team使用append方法时,每次引用不同person,元素之间相互独立,不会被原地修改。

原理图:

0f58d3fb9d80ba6f4fa8b0e03078392a.png
http://dwz.date/dA3H
http://www.pythontutor.com/visualize.html#code=team%20%3D%20%5B%5D%0Afor%20i%20in%20range%283%29%3A%0A%20%20%20%20person%20%3D%20%7B'name'%3A%20'',%20'id'%3A%200%7D%0A%20%20%20%20person%5B'id'%5D%20%3D%20i%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20team.append%28person%29%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20print%28'-'*10%29%0A%0A%0Ateam%5B0%5D%5B'name'%5D%20%3D%20'Jack'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B1%5D%5B'name'%5D%20%3D%20'Pony'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B2%5D%5B'name'%5D%20%3D%20'Crossin'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29&cumulative=true&curInstr=32&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false

第四种代码:

使用浅拷贝方法:

from copy import copy
person = {'name': '', 'id': 0}
team = []
for i in range(3):
    x = person.copy()
    x['id'] = i
    team.append(x)

team[0]['name'] = 'Jack'
team[1]['name'] = 'Pony'
team[2]['name'] = 'Crossin'

print(team)

演示:

from copy import copy
person = {'name': '', 'id': 0}
team = []
for i in range(3):
    x = person.copy()
    x['id'] = i
    print('person =',person,'nteam =',team)
    team.append(x)
    print('person =',person,'nteam =',team)
    print('-'*10)


team[0]['name'] = 'Jack'
print('person =',person,'nteam =',team)
print('-'*10)

team[1]['name'] = 'Pony'
print('person =',person,'nteam =',team)
print('-'*10)

team[2]['name'] = 'Crossin'
print('person =',person,'nteam =',team)
print('-'*10)

输出:

ee96fd22c743099327e3dce68b19d299.png

浅拷贝x = person.copy(),原始容器对象person一直未改变,每次变量x = {'name': '', 'id': 0},x 引用字典对象的值:{'name': '', 'id': 0},与第三种代码一致。

for i in range(3):     
    x = person.copy()    
    x['id'] = i

等同于

for i in range(3):
    x =  {'name': '', 'id': 0}
    x['id'] = i

原理图:

a9ef4d045fce5f913d35c2ee2144fcde.png
http://dwz.date/dA3Q
http://www.pythontutor.com/visualize.html#code=from%20copy%20import%20copy%0Aperson%20%3D%20%7B'name'%3A%20'',%20'id'%3A%200%7D%0Ateam%20%3D%20%5B%5D%0A%0Afor%20i%20in%20range%283%29%3A%0A%20%20%20%20x%20%3D%20person.copy%28%29%0A%20%20%20%20x%5B'id'%5D%20%3D%20i%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20team.append%28x%29%0A%20%20%20%20print%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0A%20%20%20%20print%28'-'*10%29%0A%0A%0Ateam%5B0%5D%5B'name'%5D%20%3D%20'Jack'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B1%5D%5B'name'%5D%20%3D%20'Pony'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0Ateam%5B2%5D%5B'name'%5D%20%3D%20'Crossin'%0Aprint%28'person%20%3D',person,'%5Cnteam%20%3D',team%29%0Aprint%28'-'*10%29%0A%0A&cumulative=true&curInstr=34&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false

参考

  1. ^例题 https://zhuanlan.zhihu.com/p/90484197
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值