字典和列表的删除问题, 深浅拷贝
一. 基础数据类型
1. str. join()
str. join(元组、列表、字典、字符串)可以把这些都转变成字符串.
a = 'hello'.join('123') b = '123'.join('hello') print(a) #1hello2hello3 print(b) #h123e123l123l123o li = ['hello','world','code'] str1 = '*'.join(li) print(str1) #hello*world*code tu = ('welcome','you','are') str2 = '@'.join(tu) print(str2) #welcome@you@are dic = {'name':'王力宏','job':'singer','age':'42'} str3 = '_'.join(dic) print(str3) #name_job_age
2. list删除
列表循环时不能不可以进行删除操作.因为删除一个元素后,剩下的索引会发生改变.一开始这个指针指向第0 个. 然后获取到第0个元素. 紧接着删除第0个. 这个时候. 原来是第一个的元素会自动的变成第0个. 然后指针向后移动一次, 指向1元素. 这时原来的1已经变成了0, 也就不会被删除了.
li = ['hello','world','code'] for c in li: li.remove(c) print(li) #['world']
li = ['hello','world','code'] for c in li: li.pop() print(li) #['hello']
li = ['hello','world','code'] for c in range(len(li)): del li[c] print(li) #报错
用pop可以删除:
li = ['hello','world','code'] for n in range(0,len(li)): li.pop() print(li) #[]
所以想要删除列表中的元素,要另建一个新列表来存储原列表的内容.对新列表进行循环,来删除原列表的元素.
li = ['hello','world','code'] li1 = [] for c in li: li1.append(c) for el in li1: li.remove(el) print(li) #[]
3. 字典增加删除
字典不能再循环的时候更改大小,所以循环的时候字典不可以增加删除.
dic1 = {"a":"123", "b":"456"} for k in dic1: dic1.setdefault("c", "123") print(dic1) #报错 RuntimeError: dictionary changed size during iteration dic2 = {"a":"321", "b":"654"} for k in dic2: dic2.pop(k) print(dic2) #报错 #RuntimeError: dictionary changed size during iteration
对字典循环删除,要先建一个新列表来存储字典的key值,再对列表循环,然后删除字典元素.
dic1 = {"a":"123", "b":"456"} li = [] for k in dic1: li.append(k) for el in li: dic1.pop(el) print(dic1) #{}
dict中的fromkey(),可以帮我们通过list来创建一个dict
dic = dict.fromkeys("王健林", "思聪" ) # 返回给你一个新字典 print(dic) #{'王': '思聪', '健': '思聪', '林': '思聪'}
4. 类型转换
元组 => 列表 list(tuple)
列表 => 元组 tuple(list)
list => str str.join(list)
str => list str.split()
三. 深浅拷贝
将一个列表赋值给lst1, 再将lst1赋值给lst2, lst1和late2的内存地址一样,共同指向同一个列表. 对lst2进行增加操作,lst1也会改变
lst1 = ["金毛狮王", "紫衫龙王", "白眉鹰王", "青翼蝠王"] lst2 = lst1 # 列表, 进行赋值操作. 实际上是引用内存地址的赋值. 内存中此时只有一个列表. 两个变量指向一个列表 lst2.append("杨左使") # 对其中的一个进行操作. 两个都跟着变 print(lst2) #['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王', '杨左使'] print(lst1) #['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王', '杨左使']
字典也是一样
dic1 = {1:"金毛狮王", 2:"紫衫龙王",3: "白眉鹰王", 4:"青翼蝠王"} dic2 = dic1 # 两个变量的内存一样,指向同一个列表. dic2.setdefault(5,"杨左使") # 对其中的一个进行操作. 两个都跟着变 print(dic2) #{1: '金毛狮王', 2: '紫衫龙王', 3: '白眉鹰王', 4: '青翼蝠王', 5: '杨左使'} print(dic1) #{1: '金毛狮王', 2: '紫衫龙王', 3: '白眉鹰王', 4: '青翼蝠王', 5: '杨左使'}
对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制一份内容. 所以. lst1(dic1)的内存指向和lst2(dic2)是一样的. lst1(dic1)改变了了, lst2(dic2)也发生了改变.
1. 浅拷贝
浅拷贝, 只会拷贝第一层. 第二层的内容不会拷贝. 所以被称为浅拷贝.用copy()来进行拷贝.
lst1 = ["赵本山", "刘能", "赵四"] lst2 = lst1.copy() # lst2 和lst1 不是一个对象了 # lst2 = lst1[:] # 也可以用切片,切片会产生新的对象 lst1.append("谢大脚") print(lst1, lst2) #['赵本山', '刘能', '赵四', '谢大脚'] ['赵本山', '刘能', '赵四']
2.深拷贝
浅拷贝只能拷贝第一层,遇到有第二层的列表,无法对第二层进行拷贝.对拷贝后的变量lst1第二层更改,lst1也会改变.
lst1 = ["超人", "七龙珠", "葫芦娃", "山中小猎人", ["金城武", "王力宏", "渣渣辉"]] lst2 = lst1.copy() # 拷贝. 浅拷贝 拷贝第一层 lst1[4].append("大阳哥") #对第二次的列表进行增加操作 print(lst1, lst2) # ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']] # ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']]
深度拷贝. 把元素内部的元素完全进行拷贝复制. 不会产生一个改变另一个跟着改变的问题.
语法 import copy
copy.deepcopy()
import copy lst1 = ["超人", "七龙珠", "葫芦娃", "山中小猎人", ["金城武", "王力宏", "渣渣辉"]] lst2 = copy.deepcopy(lst1) # 把lst1扔进去进行深度拷贝 , 包括内部的所有内容进行拷贝 lst1[4].append("大阳哥") print(lst1, lst2) # ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉', '大阳哥']] # ['超人', '七龙珠', '葫芦娃', '山中小猎人', ['金城武', '王力宏', '渣渣辉']]