pyhon 前面补充和set
Posted liuafan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pyhon 前面补充和set相关的知识,希望对你有一定的参考价值。
一, 主要内容.
补充一个字符串的基本操作
li = ["李嘉诚", "麻花藤", "黄海峰", "刘嘉玲"] s = "_".join(li) print(s) join 是把列表变成字符串,, 用前面引号里的字符串将列表连接起来 返回字符串操作 输出结果是:李嘉诚_麻花藤_黄海峰_刘嘉玲 li = "?花大闺女" s = "_".join(li) print(s) 字符串也可以添加, 输出结果是:黄_花_大_闺_女
列表:
循环删除列表中的每一个元素
来个错误范例: li = [11, 22, 33, 44] for e in li: li.remove(e) print(li) 结果是:[22, 44]
分析原因:
for的运?过程. 会有一个指针来记录当前循环的元素是哪一个, 一开始这个指针指向第0 个. 然后获取到第0个元素. 紧接着删除第0个. 这个时候. 原来是第一个的元素会?自动的变成 第0个. 然后指针向后移动一次, 指向1元素. 这时原来的1已经变成了0, 也就不会被删除了.
用pop删除试试看:
li = [11, 22, 33, 44] for i in range(0, len(li)): del li[i] print(li) 结果: 报错 # i= 0, 1, 2 删除的时候li[0] 被删除之后. 后?面?一个就变成了了第0个. # 以此类推. 当i = 2的时候. list中只有一个元素. 但是这个时候删除的是第2个 肯定报错啊
经过分析发现. 循环删除都不行. 不论是用del还是用remove. 都不能实现. 那么pop呢?
for el in li: li.pop() # pop也不行 print(li) 结果: [11, 22]
for i in range(0,len(lst))
lst.pop()
print(lst) #这个可以全删除
只有这样才是可以的:
for i in range(0, len(li)): # 循环len(li)次, 然后从后往前删除 li.pop() print(li)
或者. 用另一个列表来记录你要删除的内容. 然后循环删除
li = [11, 22, 33, 44] del_li = [] for e in li: del_li.append(e) for e in del_li: li.remove(e) print(li)
注意: 由于删除元素会导致元素的索引改变, 所以容易出现问题. 尽量不要再循环中直接去删 除元素. 可以把要删除的元素添加到另一个集合中然后再批量删除.
dict中的fromkey(),可以帮我们通过list来创建?一个dict
# fromkey() 把第一个参数中的每一项拿出来和第二个参数组成一个键值对
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic) 结果: {‘jay‘: [‘周杰伦‘, ‘麻花藤‘], ‘JJ‘: [‘周杰伦‘, ‘麻花藤‘]}
前面列表中的每一项都会作为key, 后?面列表中的内容作为value. 生成dict
注意:
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"]) print(dic) dic.get("jay").append("胡?大") print(dic) 结果: {‘jay‘: [‘周杰伦‘, ‘麻花藤‘, ‘胡?大‘], ‘JJ‘: [‘周杰伦‘, ‘麻花藤‘, ‘胡?大‘]}
代码中只是更改了 jay那个列表,但是由于jay和jj用的是同一个列表,所以,前面那个更改,后面的也会跟着更改.
(生成出来的键指向的Value是同一个对象,改变其中一个的时候,另一个也会跟着改变)
字典中的元素在迭代过程中是不允许进行删除的.
dic = {‘k1‘: ‘alex‘, ‘k2‘: ‘wusir‘, ‘s1‘: ‘?老板‘} # 删除key中带有‘k‘的元素 for k in dic: if ‘k‘ in k: del dic[k] # dictionary changed size during iteration, 在循环迭 代的时候不不允许进?行行删除操作 print(dic)
静态, 返回东西我没接 dic={} dic.fromkeys(["葫芦娃","蛇精"],["提莫","一发"]) print(dic) #什么都不打印
那该怎么办呢?要把删除的元素暂时保存在一个list中,然后循环list,再删除
dic = {‘k1‘: ‘alex‘, ‘k2‘: ‘wusir‘, ‘s1‘: ‘?老板‘} dic_del_list = [] # 删除key中带有‘k‘的元素 for k in dic: if ‘k‘ in k: dic_del_list.append(k) for el in dic_del_list: del dic[el] print(dic)
#把要删除的内容保存在一个新列表中
lst=[
lst=[‘九阴白骨抓‘,"降龙十八掌",‘乾坤大挪移‘,‘九阳神功‘]
new_lst=[]
for el lst:
new_lst.append(el)
#循环新列表,删除旧列表
for e in new_lst:
lst.remove(e)
pirnt(lat)
这是最安全的.
类型转换了解下
元组 => 列表 list(tuple)
列表 =>元组 tuple(list)
list =>str str.join(list)
str =>list str.split()
二 set 集合
set中的元素,不重复,无序的
内容必须是可哈希的(int,str,tuple,bool) 本身是不可哈希的
set里面装的key 没有value, set 也用{}表示
lst=[1,4,5,6,7,8,1,3,4,5] s=set(lst) # 去掉重复的
注意:set集合中的元素必须是可哈希的,但是set本身是不可哈希的,set是可变的
set1 = {‘1‘,‘alex‘,2,True,[1,2,3]} #报错 set2 = {‘1‘,‘alex‘,2,True,{1:2}} #报错 set3 = {‘1‘,‘alex‘,2,True,(1,2,[2,3,4])} #报错
set中的元素是不重复的,且是无序的.
s={"周润发","周结论","周润发"} print(s) 结果是:{"周润发","周结论"}
利用这个特性,我们可以使用set来去掉重复
#给list去掉重复 lst=[66,"oldsix","苍老师","oldsix","骑上",66] lst=list(set(lst)) print(lst) 结果是:[‘苍老师‘, 66, ‘骑上‘, ‘oldsix‘]
set 集合的增删改查
1,增加
###add s=set({}) s.add("王祖蓝") #添加元素 s.add("王祖贤") s.add("王祖蓝") print(s) 输出结果是:{"王祖蓝"."王祖贤") 还有一种 是 ####update s = {"李谷一", "周润发", "邓丽君", "黄家驹", "张国荣"} s.update({"越前龙马"}) print(s) 输出结果:{‘越前龙马‘, ‘李谷一‘, ‘邓丽君‘, ‘张国荣‘, ‘周润发‘, ‘黄家驹‘}
2.删除
s={"周星星","吴达达","东方不败","令狐冲"} item = s.pop() #随机弹出一个 print(s) #弹出以后剩下的集合 print(item) #弹出的是哪个元素 s.remove("东方不败") #直接删除元素 #s.remove("黄飞鸿") #由于集合中不存在这个元素,删除的话是会报错的 print(s) s.clear() #清空set集合,需要注意的是set集合如果是空的,打印出来是set() 因为要和dict 字典区分 print(s) #set()
3.修改
#set集合 是无序的, 所以没办法去定位元素 和去找索引 #只能先删除元素 再进行添加 s={"鬼脚七","陈真","黄飞红","霍元甲"} s.remove("鬼脚七") s.add("小马哥") print(s) 输出结果是:{‘小马哥‘, ‘黄飞红‘, ‘陈真‘, ‘霍元甲‘}
4.查询
#set 是一个可迭代对象,是可以进行for循环的
s={"鬼脚七","陈真","黄飞红","霍元甲"} for el in s: print(s)
5.常用操作
#交集 #两个集合中的共有元素 s1 = {"小沈阳","迪迦","懒洋洋"} s2 = {"喜洋洋","美羊羊","懒洋洋"} print(s1 & s2) #{懒洋洋} print(s1.intersection(s2)) #{懒洋洋}
# 并集 # print(s1 | s2) # print(s1.union(s2)) # 并集
#差集
# s1 = {"刘能", "赵四", "皮长山"} # s2 = {"刘科长", "冯乡长", "皮长山"} # 差集, 把自己本身中和对方不相关的内容留下 # print(s2 - s1) # print(s2.difference(s1))
# 反交集 print(s1 ^ s2) # 两个集合中单独存在的数据 {‘冯乡?长‘, ‘刘能‘, ‘刘科?长‘, ‘赵四‘} print(s1.symmetric_difference(s2)) # {‘冯乡?长‘, ‘刘能‘, ‘刘科?长‘, ‘赵四‘}
s1 = {"刘能", "赵四"} s2 = {"刘能", "赵四", "?皮?长?山"} # 子集 print(s1 < s2) # set1是set2的?子集吗? True print(s1.issubset(s2)) # 超集 print(s1 > s2) # set1是set2的超集吗? False print(s1.issuperset(s2))
set集合本身是可以发生改变的,是不可hash的,我们可以使用frozenset来保存数据
frozenset是不可变的,也就是一个可哈希的数据类型
s = frozenset(["赵本山", "刘能", "??山", "?跪"]) dic = {s:‘123‘} # 可以正常使用了 print(dic) 这个不是很常用,了解一下
三 深浅拷贝
lst1 =["金毛狮王","紫衫龙王","白眉鹰王","青翼蝠王"] lst2 = lst1 print(lst1) print(lst2) #两个输出的是一样的 lst1.append("杨晓") print(lst1) print(lst2) 输出结果是: [‘金毛狮王‘,‘紫衫龙王‘,‘白眉鹰王‘,‘青翼蝠王‘,‘杨晓‘] [‘金毛狮王‘,‘紫衫龙王‘,‘白眉鹰王‘,‘青翼蝠王‘,‘杨晓‘]
dic1 = {"id": 123, "name": "谢逊"}
dic2 = dic1
print(dic1)
print(dic2)
dic1[‘name‘] = "范瑶"
print(dic1)
print(dic2)
结果:
{‘id‘: 123, ‘name‘: ‘谢逊‘}
{‘id‘: 123, ‘name‘: ‘谢逊‘}
{‘id‘: 123, ‘name‘: ‘范瑶‘}
{‘id‘: 123, ‘name‘: ‘范瑶‘}
对于list,set,dict来说,直接赋值,其实是把内存地址交给变量,并不是复制一份内容,所以,
lst1的内存指向和lst2是一样的.lst1改变了,lst2也发生了改变
浅拷贝
lst1 = ["何炅", "杜海涛","周渝民"] lst2 = lst1.copy() lst1.append("李嘉诚") print(lst1) print(lst2) print(id(lst1), id(lst2)) 结果: 两个lst完全不一样,内存地址和内容也不一样,发现实现了内存的拷贝 lst1 = ["何炅", "杜海涛","周渝民", ["麻花藤", "?芸", "周笔畅"]] lst2 = lst1.copy() lst1[3].append("?敌是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3])) 结果: [‘何炅‘, ‘杜?涛‘, ‘周渝民‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]] [‘何炅‘, ‘杜?涛‘, ‘周渝民‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]] 4417248328 4417248328
浅拷贝,只会拷贝第一层,第二层的内容不会拷贝,所以被称为浅拷贝
深拷贝
import copy lst1 = ["何炅", "杜?涛","周渝民", ["麻花藤", "?芸", "周笔畅"]] lst2 = copy.deepcopy(lst1) lst1[3].append("?敌是多磨寂寞") print(lst1) print(lst2) print(id(lst1[3]), id(lst2[3])) 结果: [‘何炅‘, ‘杜海涛‘, ‘周渝民‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]] [‘何炅‘, ‘杜海涛‘, ‘周渝民‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘]] 4447221448 4447233800
都不一样了,深度拷贝,把元素内部的元素完全进行拷贝复制,不会产生一个改变以另一个跟着
改变的问题
以上是关于pyhon 前面补充和set的主要内容,如果未能解决你的问题,请参考以下文章
数据结构( Pyhon 语言描述 ) — —第11章:集和字典