Python入门-深浅拷贝
Posted 快乐的--猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python入门-深浅拷贝相关的知识,希望对你有一定的参考价值。
首先我们在这里先补充一下基础数据类型的一些知识:
一.循环删除
1.前面我们学了列表,字典和集合的一些操作方法:增删改查,现在我们来看一下这个问题:
有这样一个列表: lst = [‘周杰伦‘,‘周润发‘,‘周星驰‘,‘刘德华‘]
如果现在要求我们删除带‘周‘的元素,我们下意识会这样做:
lst = [‘周杰伦‘,‘周润发‘,‘周星驰‘,‘刘德华‘] for i in lst: if ‘周‘ in i: lst.remove(i) print(lst) #[‘周润发‘, ‘刘德华‘]
但是结果却是不对,没有删干净,这是为什么,这是因为python内部的机制不允许在for循环内部删除元素,同样的字典同样如此:
dic = {‘周杰伦‘:‘jay‘,‘周润发‘:‘发哥‘,‘周星驰‘:‘星爷‘,‘刘德华‘:‘华仔‘} for i in dic: if ‘周‘ in i: dic.pop(i) print(dic) #报错:dictionary changed size during iteration.字典在循环过程中改变了大小
集合同样,在这里就不多说了,有兴趣可以自己私底下去敲一敲.
那么就没办法删除吗?当然有,还用上边的例子,不过要加点东西:
dic = {‘周杰伦‘:‘jay‘,‘周润发‘:‘发哥‘,‘周星驰‘:‘星爷‘,‘刘德华‘:‘华仔‘} lst = [] #建一个列表 for i in dic: if ‘周‘ in i: lst.append(i) #把符合条件的添加到列表当中, for l in lst: #然后循环这个这列表 dic.pop(l) #再删除对应的键值对 print(dic) #{‘刘德华‘: ‘华仔‘}
这样我们就拿到了我们想要的东西了,列表也是同样的操作,自己私下里可以练练.
2.字符串与列表
关于字符串也有一个知识点我们没有说,
lst = [‘周杰伦‘,‘周润发‘,‘周星驰‘,‘刘德华‘] s = ‘_‘.join(lst) print(s) #周星驰_周润发_刘德华_周杰伦
输出的是字符串类型,如果以后有列表转化成字符串的操作就可以用join了,那与之对应的是什么呢?
s = ‘周星驰_周润发_刘德华_周杰伦‘ lst = s.split(‘_‘) print(lst) #[‘周杰伦‘,‘周润发‘,‘周星驰‘,‘刘德华‘]
那就是我们之前说过的split,它输出的是列表类型,把字符串转换成列表类型
我们再来补充几个常见的陷阱问题:
陷阱1:
fromkeys()帮我们创建字典用的,把第一个参数进行迭代,拿到每一项作为key和后面的value组合成字典
d = dict.fromkeys(‘张无忌‘,‘赵敏‘) #创建字典 print(d) #{‘张‘: ‘赵敏‘, ‘无‘: ‘赵敏‘, ‘忌‘: ‘赵敏‘}
返回的是新字典,和原来的字典没有关系
dic = {} d = dic.fromkeys("风扇哥", "很困") print(dic) # {} print(d) #{‘风‘: ‘很困‘, ‘扇‘: ‘很困‘, ‘哥‘: ‘很困‘}
陷阱2:
如果value是可变的数据类型,那么其中一个key对应的value执行的更改操作,其他的也跟着变
d = dict.fromkeys("胡辣汤", []) print(d) # {‘胡‘: [], ‘辣‘: [], ‘汤‘: []} print(id(d[‘胡‘]))#32118600 print(id(d[‘辣‘]))#32118600 print(id(d[‘汤‘]))#32118600
d[‘胡‘].append(‘河南特色‘)
print(d)# {‘胡‘: [‘河南特色‘], ‘辣‘: [‘河南特色‘], ‘汤‘: [‘河南特色‘]}
接下来就让我们来看看今天最重要的内容:深浅拷贝
二.深浅拷贝
lst1 = [‘周星驰‘,‘周润发‘,‘周杰伦‘,‘刘德华‘] lst2 = lst1 print(lst1) print(lst2) lst1.append(‘梁朝伟‘) print(lst1) print(lst2) 结果: [‘周星驰‘, ‘周润发‘, ‘周杰伦‘, ‘刘德华‘] [‘周星驰‘, ‘周润发‘, ‘周杰伦‘, ‘刘德华‘] [‘周星驰‘, ‘周润发‘, ‘周杰伦‘, ‘刘德华‘, ‘梁朝伟‘] [‘周星驰‘, ‘周润发‘, ‘周杰伦‘, ‘刘德华‘, ‘梁朝伟‘] dic = {‘周润发‘:‘发哥‘,‘周星驰‘:‘星爷‘} dic1 = dic print(dic) print(dic1) dic[‘周杰伦‘] = ‘jay‘ print(dic) print(dic1) 结果: {‘周润发‘: ‘发哥‘, ‘周星驰‘: ‘星爷‘} {‘周润发‘: ‘发哥‘, ‘周星驰‘: ‘星爷‘} {‘周润发‘: ‘发哥‘, ‘周星驰‘: ‘星爷‘, ‘周杰伦‘: ‘jay‘} {‘周润发‘: ‘发哥‘, ‘周星驰‘: ‘星爷‘, ‘周杰伦‘: ‘jay‘}
对于列表,字典,集合来说,直接赋值其实是把内存地址交给变量,并不是复制一份内容,所以,lst1的内容指向和lst2是一样的,lst1改变了,lst2也发生了改变
浅拷贝:
lst1 = [‘周润发‘,‘周星驰‘,‘周杰伦‘,‘刘德华‘] lst2 = lst1.copy() lst1.append(‘梁朝伟‘) print(lst1) print(lst2) print(id(lst1),id(lst2)) 结果: [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘, ‘梁朝伟‘] [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘] 37492552 31136264 内存地址和内容都不一样了,实现了拷贝 lst1 = [‘周润发‘,‘周星驰‘,‘周杰伦‘,‘刘德华‘,[‘刘嘉玲‘,‘莫文蔚‘,‘昆凌‘,‘陈慧琳‘]] lst2 = lst1.copy() lst1[4].append(‘都是美女‘) print(lst1) print(lst2) print(id(lst1),id(lst2)) 结果: [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘, [‘刘嘉玲‘, ‘莫文蔚‘, ‘昆凌‘, ‘陈慧琳‘, ‘都是美女‘]] [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘, [‘刘嘉玲‘, ‘莫文蔚‘, ‘昆凌‘, ‘陈慧琳‘, ‘都是美女‘]] 37820232 37820232
浅拷贝拷贝的只是第一层的内容,所以才叫浅拷贝
深拷贝:
import copy lst1 = [‘周润发‘,‘周星驰‘,‘周杰伦‘,‘刘德华‘,[‘刘嘉玲‘,‘莫文蔚‘,‘昆凌‘,‘陈慧琳‘]] lst2 = copy.deepcopy(lst1) lst1[4].append(‘都是美女‘) print(lst1) print(lst2) print(id(lst1),id(lst2)) 结果: [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘, [‘刘嘉玲‘, ‘莫文蔚‘, ‘昆凌‘, ‘陈慧琳‘, ‘都是美女‘]] [‘周润发‘, ‘周星驰‘, ‘周杰伦‘, ‘刘德华‘, [‘刘嘉玲‘, ‘莫文蔚‘, ‘昆凌‘, ‘陈慧琳‘]] 39434696 39435656
内容和内存地址都不一样了,深拷贝就是把里面的内容都拷贝下来,变成内容相同内存地址不同的两个列表,好了,最后给大家留一道练习题:
a = [1,[2]] a[1] = a print(a[1])
以上是关于Python入门-深浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章