基础数据补充
字符串的常用操作
1. join()
li = ["李嘉诚", "麻花藤", "⻩海峰", "刘嘉玲"] s = "_".join(li) print(s) li = "床前明月光" s = "_".join(li) print(s)
运行结果:
李嘉诚_麻花藤_黄海峰_刘嘉玲
床_前_明_月_光
Process finished with exit code 0
总结:join()在列表和字符串中,将join前的数组均匀插入其中,形成一个str类型。
2. 循环删除列表中每一个元素
li = [1, 2, 3, 4, 5, 6, 7, 8, 9] for e in li: li.remove(e) print(li)
运行结果:
[2, 4, 6, 8]
Process finished with exit code 0
分析:当我们删除第一个值1时,第二个值2将塞到第一位,这造成了当第奇数个值被删掉以后,第偶数个的值便会完美填充,导致无法完全删除。
li = [1, 2, 3, 4] for i in range(0, len(li)): del li[i] print(li)
运行结果:
IndexError: list assignment index out of range
Process finished with exit code 1
分析:当删除li[0]之后,后面的2就会变为第零个,当i=2,删除第三个时,list中只有一个元素,所以报错。
li = [1, 2, 3, 4] for i in li: li.pop() print(li)
运行结果:
[1, 2]
Process finished with exit code 0
分析:pop()默认值为-1,即删除最后一项。当i为1时,删掉4,剩余三项;当i为2时,删掉3,剩余两项,此时list中已经遍历两次且只有两项,所以不能再遍历了,在这里有点类似remove()删除。下面将展示可行方法:
方法1:
li = [1, 2, 3, 4] for i in range(0, len(li)): # 遍历len(list)次,全部删除 li.pop() print(li)运行结果:
[]
Process finished with exit code 0
结论:pop()删除应该遍历列表长度的次数。
方法2:
li = [1, 2, 3, 4] delLi = [] for i in li: delLi.append(i) for e in delLi: # 遍历得到的新的要删除的列表,遍历的次数为len(delLi)次 li.remove(e) print(li)
结论:将要删除的元素添加到新的且要删除的列表中,遍历得到的新的要删除的列表,遍历的次数为len(delLi)次。
fromkey()
fromkey()是字典中的常用方法,使用这个函数我们可以通过list来创建一个dict。
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic)
运行结果:
{'JJ': ['周杰伦', '麻花藤'], 'jay': ['周杰伦', '麻花藤']}
Process finished with exit code 0
结论:前面的每一项都会作为key,后面列表中的内容生成value,生成一个dict。
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic) dic.get("jay").append("胡⼤") print(dic)
运行结果:
{'jay': ['周杰伦', '麻花藤'], 'JJ': ['周杰伦', '麻花藤']}
{'jay': ['周杰伦', '麻花藤', '胡大'], 'JJ': ['周杰伦', '麻花藤', '胡大']}
Process finished with exit code 0
结论:表面上来说只是改变了jay那个列表,但实际上jay和JJ共用的是同一个列表。所以,改一则全改!
dict迭代删除
dic = {'k1': 'python', 'k2': 'java', 's1': 'Hello'} # 删除key中带有'k'的元素 for k in dic: if 'k' in k: del dic[k] # dictionary changed size during iteration, 在循环迭代的时候不允许进⾏删除操作 print(dic)
运行结果:
RuntimeError: dictionary changed size during iteration
Process finished with exit code 1
结论:字典在迭代过程中不能大小不能被改变。正确方法如下:
dic = {'k1': 'python', 'k2': 'java', 's1': 'Hello'} dicDelList = [] # 删除key中带有'k'的元素 for k in dic: if 'k' in k: dicDelList.append(k) # 删除元素的新列表 for el in dicDelList: del dic[el] print(dic)运行结果:
{'s1': 'Hello'}
Process finished with exit code 0
结论:当迭代删除字典中的元素时,由于字典在迭代过程中大小不能改变,所以我们应该新建一个新的要删除的列表,将欲删除的元素添加其中,然后迭代该列表再行删除。
类型转换
1. 元组转列表
list(tuple)
2. 列表转元组
tuple(list)
3. list转str
str.join(list)
4. str转list
str.split()
5. 代表着False的数据:
0,"",None,[],(),{},set()
set集合
set集合概述
set集合是python的一个基本数据类型,一般不是很常用。set中的元素是不重复的,无序的,里面的元素必须是可hash的(int, str, tuple,bool),我们可以这样来记,set就是dict类型的数据但是不保存value,只保存key。set也用{}表示。
注意: set集合中的元素必须是可hash的,但是set本身是不可hash得,set是可变的。
set1 = {'1','hello',2,True,[1,2,3]} # 报错,里面有列表
set2 = {'1','hello',2,True,{1:2}} # 报错,里面有字典
set3 = {'1','hello',2,True,(1,2,[2,3,4])} # 报错,里面有元组
set表示集合,集合具有三大性质:无序性、互异性、确定性。
可利用set集合来去重。
set集合增删改查
1. 增加
s = {"刘嘉玲", '关之琳', "王祖贤"} s.add("郑裕玲") print(s) s.add("郑裕玲") # 重复的内容不会被添加到set集合中 print(s) s = {"刘嘉玲", '关之琳', "王祖贤"} s.update("麻花藤") # 迭代更新 print(s) s.update(["张曼⽟", "李若彤", "李若彤"]) print(s)
运行结果:
{'关之琳', '郑裕玲', '王祖贤', '刘嘉玲'}
{'关之琳', '郑裕玲', '王祖贤', '刘嘉玲'}
{'王祖贤', '藤', '麻', '刘嘉玲', '花', '关之琳'}
{'王祖贤', '李若彤', '藤', '麻', '刘嘉玲', '花', '关之琳', '张曼玉'}
Process finished with exit code 0
总结:
增加用add()。
重复的值无法添加到set集合中。
使用update("HHH"),将字符串中的每一个元素不重复的添加进去形成新的列表。
使用update(["A","B","C"])将列表中的每个元素不重复的添加进去形成新的列表。
2. 删除
s = {"刘嘉玲", '关之琳', "王祖贤", "张曼⽟", "李若彤"} item = s.pop() # 随机弹出⼀个. print(s) print(item) s.remove("关之琳") # 直接删除元素 # s.remove("马⻁疼") # 不存在这个元素. 删除会报错 print(s) s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和dict区分的. print(s) # set()
运行结果:
{'关之琳', '王祖贤', '张曼玉', '李若彤'}
刘嘉玲
{'王祖贤', '张曼玉', '李若彤'}
set()
Process finished with exit code 0
总结:(略)
3. 修改
s = {"刘嘉玲", '关之琳', "王祖贤", "张曼⽟", "李若彤"} # 把刘嘉玲改成赵本⼭ s.remove("刘嘉玲") s.add("赵本山") print(s)
运行效果:
{'王祖贤', '张曼玉', '李若彤', '关之琳', '赵本山'}
Process finished with exit code 0
总结:
set集合中的数据没有索引. 也没有办法去定位某个元素. 所以没有办法进行直接修改。 我们可以采用先删除后添加的形式式来完成修改操作。
4. 查询
s = {"刘嘉玲", '关之琳', "王祖贤", "张曼⽟", "李若彤"} for el in s: print(el)
运行结果:
李若彤
张曼玉
刘嘉玲
关之琳
王祖贤
Process finished with exit code 0
结论:set是是个可迭代对象. 所以可以进行for循环。
5. 常用操作
交集
s1 = {"刘能", "赵四", "⽪长⼭"} s2 = {"刘科长", "冯乡长", "⽪长⼭"} print(s1 & s2) # {'⽪长⼭'} print(s1.intersection(s2)) # {'⽪长⼭'}运行结果:
{'皮长山'}
{'皮长山'}
Process finished with exit code 0
并集
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} print(s1 | s2) print(s1.union(s2))
运行结果:
{'刘能', '赵四', '刘科长', '皮长山', '冯乡长'}
{'刘能', '赵四', '刘科长', '皮长山', '冯乡长'}
Process finished with exit code 0
差集
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} print(s1 - s2) print(s1.difference(s2))
运行结果:
{'赵四', '刘能'}
{'赵四', '刘能'}
Process finished with exit code 0
反交集
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} print(s1 ^ s2) print(s1.symmetric_difference(s2))
运行结果:
{'刘科长', '赵四', '刘能', '冯乡长'}
{'刘科长', '赵四', '刘能', '冯乡长'}
Process finished with exit code 0
子集
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} print(s1 < s2) print(s1.issubset(s2))
运行结果:
False
False
Process finished with exit code 0
超集
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} print(s1 > s2) print(s1.issuperset(s2))
运行结果:
False
False
Process finished with exit code 0
frozenset()
set集合本身是可以发生改变的. 是不可hash的. 我们可以使用frozenset来保存数据。
frozenset是不可变的. 也就是一个可哈希的数据类型。
s = frozenset(["赵本⼭", "刘能", "皮长山", "长跪"]) dic = {s: '123'} print(dic)
运行结果:
{frozenset({'长跪', '赵本山', '皮长山', '刘能'}): '123'} # 可保存为字典的key值。
Process finished with exit code 0
深浅拷贝
请您查看代码1:lst1 = ["⾦⽑狮王", "紫衫龙王", "⽩眉鹰王", "⻘翼蝠王"] lst2 = lst1 print(lst1) print(lst2) lst1.append("杨逍") print(lst1) print(lst2)
运行结果:
['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王']
['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王']
['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王', '杨逍']
['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王', '杨逍']
Process finished with exit code 0
请您查看代码2:
dic1 = {"id": 123, "name": "谢逊"} dic2 = dic1 print(dic1) print(dic2) dic1['name'] = "范瑶" print(dic1) print(dic2)
运行结果:
{'name': '谢逊', 'id': 123}
{'name': '谢逊', 'id': 123}
{'name': '范瑶', 'id': 123}
{'name': '范瑶', 'id': 123}
Process finished with exit code 0
总结:对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制一份内容. 所以.lst1的内存指向和lst2是一样的. lst1改变了, lst2也发生了改变。
浅拷贝
请您查看代码:
lst1 = ["何炅", "杜海涛","周渝⺠"] lst2 = lst1.copy() lst1.append("李嘉诚") print(lst1) print(lst2) print(id(lst1), id(lst2))运行结果:
['何炅', '杜海涛', '周渝民', '李嘉诚']
['何炅', '杜海涛', '周渝民']
14193480 14193416
Process finished with exit code 0
结论:两个lst完全不一样. 内存地址和内容也不一样. 发现实现了内存的拷贝。
请您查看代码:
lst1 = ["何炅", "杜海涛", "周渝⺠", ["麻花藤", "马芸", "周笔畅"]] lst2 = lst1.copy() lst1[3].append("⽆敌是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3]))
运行结果:
['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
13996872 13996872
Process finished with exit code 0
结论:只会拷贝第一层,第二层的内容不会拷贝,称为浅拷贝。
深拷贝
在使用深拷贝的时候必须引入包。
import copy
import copy lst1 = ["何炅", "杜海涛", "周渝⺠", ["麻花藤", "马芸", "周笔畅"]] lst2 = copy.deepcopy(lst1) lst1[3].append("无敌是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3]))
运行结果:
['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅']]
14601416 14601480
Process finished with exit code 0
结论:深度拷贝 把元素内部的元素完全进行拷贝复制. 不会产生一个改变另一个跟着改变的问题。
面试题
a = [1, 2] a[1] = a print(a[1])
运行结果:
[1, [...]]
Process finished with exit code 0
理由:a[1] = 2,现在又等于一个列表a,如此一下去a[1]永远等于一个列表,所以这是个无限得嵌套列表。