Python之基础数据补充、set集合和深浅拷贝

基础数据补充

字符串的常用操作

        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: # 遍历得到的新的要删除的列表,遍历的次数为lendelLi)次
    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]永远等于一个列表,所以这是个无限得嵌套列表。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值