p08_列表、字典、集合迭代问题

文章讨论了Python中列表和字典的内存管理机制,特别是当在遍历过程中删除元素时如何避免内存收缩导致的意外效果。通过浅拷贝和深拷贝的方式,提出了解决遍历问题的方法,以及在处理字典和集合时需要注意的问题.
摘要由CSDN通过智能技术生成

列表内存自动管理

思考:下面程序的输出结果是什么?

为什么没有得到空列表?

如果原列表在内存中为:

for 循环是按照索引来遍历元素的,第一次循环取索引 0 对应的元素(即元素

1 ),然后再执行 remove() 方法删除它,此时列表内存会进行收缩,使得后面

的元素 2 、 3 都往前移动,则列表在内存中变为:

lis = [ 1 , 2 , 3 ]
for item in lis:
lis.remove(item)
print(lis)

而因为内存收缩就导致了第二次循环取索引 1 对应的元素时就取到了元素 3 ,然

后再执行 remove() 方法删除它,列表就变为:

列表内存自动管理功能: 在删除列表中的元素时,Python会自动对列表内存

进行收缩,并移动列表中的元素以保证元素之间没有间隙,所以遍历删除列表

中的元素时,被删元素后面的值会向前顶,导致漏删。

如何解决这个问题呢?

思路:遍历一个新的列表,不受原数据修改的影响即可

import copy

lis = [ 1 , 2 , 3 ]
lis2 = [ 1 , 2 , 3 ]  # 思考:换成 lis2 = lis 是否可以?
for item in lis2:
lis.remove(item)
print(lis)

lis = [ 1 , 2 , 3 ]
for item in lis[:]:  # 浅拷贝
lis.remove(item)
print(lis)

lis = [ 1 , 2 , 3 ]
lis2 = lis.copy()  # 浅拷贝
for item in lis2:
lis.remove(item)
print(lis)

lis = [ 1 , 2 , 3 ]
lis2 = copy.copy(lis)  # 浅拷贝
for item in lis2:
lis.remove(item)
print(lis)

lis = [ 1 , 2 , 3 ]
lis2 = copy.deepcopy(lis)  # 深拷贝
for item in lis2:
lis.remove(item)
print(lis)

字典、集合遍历问题

字典、集合在遍历时,如果改变原数据的size,则会造成迭代时报错

lis = [ 1 , 2 , 3 ]
lis2 = list(lis)  # 返回一个新的对象,同理:tuple()/set()也
可以
for item in lis2:
lis.remove(item)
print(lis)
dic = {"name": "Tom", "age": 18 , "height": 188 }
for key in dic:
dic.pop(key)  # 改变了原数据大小,所以报错
print(dic)
dic = {"name": "Tom", "age": 18 , "height": 188 }
for key in dic:
dic.update({"weight": 88 })  # 改变了原数据大小,所以报错
print(dic)
dic = {"name": "Tom", "age": 18 , "height": 188 }
for key in dic:
dic.update({"age": 22 })  # 没有改变原数据大小,所以不报错
print(dic)
set1 = {"name", "age", "height"}

解决思路:遍历一个新的字典/集合,不受原数据修改的影响即可

for key in set1:
set1.pop()  # 改变了原数据大小,所以报错
print(set1)
set1 = {"name", "age", "height"}
for key in set1:
set1.add("weight")  # 改变了原数据大小,所以报错
print(set1)
set1 = {"name", "age", "height"}
for key in set1:
set1.add("age")  # 没有改变原数据大小,所以不报错
print(set1)
import copy
dic = {"name": "Tom", "age": 18 , "height": 188 }
dic2 = {"name": "Tom", "age": 18 , "height": 188 }  # 思考:
换成 dic2 = dic 是否可以?
for key in dic2:
dic.pop(key)
print(dic)
dic = {"name": "Tom", "age": 18 , "height": 188 }
dic2 = dic.copy()  # 浅拷贝
for key in dic2:
dic.pop(key)

print(dic)

dic = {“name”: “Tom”, “age”: 18 , “height”: 188 }
dic2 = copy.copy(dic)  # 浅拷贝
for key in dic2:
dic.pop(key)
print(dic)

dic = {“name”: “Tom”, “age”: 18 , “height”: 188 }
dic2 = copy.deepcopy(dic)  # 深拷贝
for key in dic2:
dic.pop(key)
print(dic)

dic = {“name”: “Tom”, “age”: 18 , “height”: 188 }
key_list = list(dic)  # 返回一个新的对象,同理:
tuple()/set()也可以
for key in key_list:
dic.pop(key)
print(dic)

dic = {“name”: “Tom”, “age”: 18 , “height”: 188 }
dict_keys = dic.keys()  # 思考:这样可以吗?
for key in dict_keys:
dic.pop(key)
print(dic)

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值