一、基本数据类型补充

1,关于int和str在之前的学习中已经介绍了80%以上了,现在再补充一个字符串的基本操作:

   li = ['李嘉诚','何炅','海峰','刘嘉玲']
s = "_".join(li)
print(s) # 结果为:李嘉诚_何炅_海峰_刘嘉玲 li = '黄花大闺女'
s = "_".join(li)
print(s) # 结果为:黄_花_大_闺_女

2,列表相关:

  循环删除列表中的每一个元素,有如下代码,注意结果并分析原因:

  li = [11,22,33,44]
for e in li:
li.remove(e)
print(li) # 结果为:[22, 44]

分析原因:for的运行过程中,会有一个指针来记录当前循环的元素是哪一个,一开始这个指针指向第0个,然后获取到第0个元素,紧接着删除第0个,这个时候,原来第一个元素会自动的变成第0 个元素,然后指针向后移动一次,指向1元素,这时原来的1变成了0,也就不会被删除了。

用range()删除试试看,如下代码:

    li = [11,22,33,44]
for e in range(0,len(li)):
del li[i]
print(li)
# 结果:报错
# i = 0,1,2 删除的时候,li[0]被删除之后,后一个就变成了第0个,以此类推
# 当i = 2的时候,list中只有一个元素,但是这个时候删除的是第2个,所以会报错
复制代码

经分析发现,循环删除都不行,不论用del还是remove,都不能实现,那么用pop呢?具体如下:

 li = [11,22,33,44]
for el in li:
li.pop()
print(li) # 结果为:[11, 22],所以pop也不能完全删除

所以下面这样是可以的:

 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)

注意:由于删除元素会导致元素的索引改变,所以容易出现问题,因此尽量不要在循环中直接去删除元素,可以把要删除的元素添加到另一个集合中然后再批量删除。

3,字典(dict)中的fromkeys()可以帮我们通过list来创建一个dict, 需要注意的是formkeys直接使用类名(dict)进行访问,具体代码如下:

 dic = dict.fromkeys(["jay","JJ"],["周杰伦","麻花藤"])
print(dic)
# 结果为:{'jay': ['周杰伦', '麻花藤'], 'JJ': ['周杰伦', '麻花藤']}

  可以看出,前面的列表中的每一项都会作为key,后面列表中的内容作为value,生产dict。

现在请看下面一段代码:

dic = dict.fromkeys(["jay","JJ"],["周杰伦","麻花藤"])
print(dic) # 结果为:{'jay': ['周杰伦', '麻花藤'], 'JJ': ['周杰伦', '麻花藤']}
dic.get("jay").append("胡大")
print(dic)
# 结果为:{'jay': ['周杰伦', '麻花藤', '胡大'], 'JJ': ['周杰伦', '麻花藤', '胡大']}

可以看出,代码中只是更改了jay那个列表,但是由于jay和JJ用的是同一个列表,所以,前面那个改了,后面那个也会跟着改。

4,字典(dict)中的元素在迭代过程中是不允许进行删除的,如下代码:

   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)

那怎么办呢?把要删除的元素暂时先保存在一个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)

5,类型转换

元组 = > 列表  list(tuple)

列表 = > 元组  tuple(list)

list  = >  str   str.join(list)

str  = >  list   str.split()

能转换成False的数据:0,’’,None,[],(),{},set() =>False

二、集合

set(集合)是python的一个基本数据类型,一般不是很常用,set中的元素是不重复的,无序的,里面的元素必须是可hash的(int,tuple,bool),我们可以这样来记,set就是dict类型的数据但是不保存value,只保存key,set也用{}表示。

注意:set集合中的元素必须是可hash的,但是set本身是不可hash,set是可变的。

    set1 = {'','alex',2,True,[1,2,3]} # 报错
set2 = {'','alex',2,True,{1:2}} # 报错
set3 = {'','alex',2,True,(1,2,[2,3,4])} # 报错

set中的元素是不可重复的,且无序的,如下代码:

    s = {"周杰伦", "周杰伦", "周星星"}
print(s) # 结果为:{'周星星', '周杰伦'},也可能为:{'周杰伦', '周星星'}

使用这个特性,我们可以使用set来去掉自动重复,如下代码:

  # 给list去重复
lst = [45 , 5 , "哈哈", 45 , '哈哈', 50]
lst = list(set(lst)) # 把list转换成set, 然后再转换回list
print(lst)

如何创建一个空字典和一个空集合:

    d = {}   #创建一个空字典
s = set() #创建一个空集合

1,增加

集合的增加操作有:add,update(迭代更新),具体代码如下示例:

s = {"刘嘉玲", '关之琳', "王祖贤"}
s.add("郑裕玲")
print(s)
s.add("郑裕玲") # 重复的内容不会被添加到set集合中
print(s)
s = {"刘嘉玲", '关之琳', "王祖贤"}
s.update("麻花藤") # 迭代更新
print(s)
s.update(["张曼玉","李若彤","李若彤"])
print(s)

2,删除

集合的删除操作有:pop,remove,clear,具体代码如下示例:

    s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"}
item = s.pop() # 随机弹出⼀个.返回所弹出的元素
print(s)
print(item) s.remove("关之琳") # 直接删除元素
# s.remove("马⻁疼") # 删除不存在的元素. 会报错
print(s) s.clear()
# 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和dict区分的.
print(s) # 结果为:set()

3,修改

集合中的数据没有索引. 也没有办法去定位⼀个元素. 所以没有办法进⾏直接修改,我们可以采⽤先删除后添加的⽅式来完成修改操作,具体如下示例:

    s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"}
# 把刘嘉玲改成赵本山
s.remove("刘嘉玲")
s.add("赵本山")
print(s)

4,查询

set是一个可迭代对象. 所以可以进行for循环,具体如下:

    for el in s:
print(el)

5,其他常见操作

集合的常见操作还有:&(交集),|(并集),-(差集),^(反交集),<(子集),>(超集),具体如下示例:

s1 = {"刘能", "赵四", "皮长山"}
s2 = {"刘科长", "冯乡长", "皮长山"}
# 交集:两个集合中的共有元素
print(s1 & s2) # {'皮长山'}
print(s1.intersection(s2)) # {'皮长山'}
# 并集
print(s1 | s2) # {'刘科长', '冯乡长', '赵四', '皮长山', '刘能'}
print(s1.union(s2)) # {'刘科长', '冯乡长', '赵四', '皮长山', '刘能'}
# 差集
print(s1 - s2) # {'赵四', '刘能'} 得到第⼀个中单独存在的
print(s1.difference(s2)) # {'赵四', '刘能'}
# 反交集
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:''} # 可以正常使用了
print(dic)

  这个不是很常用,了解一下就可以了。

三、深浅拷贝

3.1 分析如下代码的运行结果:

 lst1 = ["金毛狮王", "紫衫龙王", "白眉鹰王", "青翼蝠王"]
lst2 = lst1
print(lst1 is lst2) # 结果为:True,lst1和lst2指向同一个列表
lst1.append("杨逍")
print(lst1) #结果为:['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王']
print(lst2) #结果为:['金毛狮王', '紫衫龙王', '白眉鹰王', '青翼蝠王'] dic1 = {"id": 123, "name": "谢逊"}
dic2 = dic1
print(dic1 is dic2) #结果为:True,dic1和dic2指向同一个字典
dic1['name'] = "范瑶"
print(dic1) #结果为:{'id': 123, 'name': '范瑶'}
print(dic2) #结果为:{'id': 123, 'name': '范瑶'}

  对于list,dict,set来说,直接赋值,其实是把内存地址交给变量,并不是复制一份内容,所以lst1的内存指向和lst2是一样的,lst1改变了,lst2也发生了改变。

3.2 浅拷贝:浅拷贝只是拷贝第一层,第二层的内容不会拷贝,所以被称为浅拷贝。具体示例如下:

    lst1 = ["何炅", "杜海涛","周渝民"]
lst2 = lst1.copy() #或者可以用lst2 = lst1[:],列表切片产生新列表
lst1.append("李嘉诚")
print(lst1) #结果为:['何炅', '杜海涛', '周渝民', '李嘉诚']
print(lst2) #结果为:['何炅', '杜海涛', '周渝民']
print(id(lst1) is id(lst2)) #False
# 结果:两个lst完全不⼀样. 内存地址和内容也不一样. 发现实现了内存的拷贝
lst1 = ["何炅", "杜海涛","周渝民", ["麻花藤", "马芸", "周笔畅"]]
lst2 = lst1.copy()
lst1[3].append("无敌是多磨寂寞")
print(lst1) #结果为:['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
print(lst2) #结果为:['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
print(id(lst1[3]) , id(lst2[3])) #40938504 40938504
print(id(lst1[3]) is id(lst2[3])) # False 此处不明白为什么返回False,这是一个疑问点???

3.3 深拷贝:深拷贝是把元素内部的元素完全进行拷贝复制,不会产生一个改变另一个跟着改变的问题。如下:

import copy   # 引入模块
lst1 = ["何炅", "杜海涛","周渝民", ["麻花藤", "马芸", "周笔畅"]]
lst2 = copy.deepcopy(lst1)
lst1[3].append("无敌是多磨寂寞")
print(lst1)
#结果为:['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅', '无敌是多磨寂寞']]
print(lst2)
#结果为:['何炅', '杜海涛', '周渝民', ['麻花藤', '马芸', '周笔畅']]
print(id(lst1[3]) is id(lst2[3])) # 43643784 43645384,内存地址不一样

最新文章

  1. 【转】关于Jquery中ajax方法data参数用法的总结
  2. Codeforces Round #371 (Div. 2) C. Sonya and Queries[Map|二进制]
  3. gradle基础的build文件模板_jetty
  4. study topics
  5. 浅谈Redis数据库的键值设计(转)
  6. 解决Ubuntu14.04下Clementine音乐播放器不能播放wma文件的问题
  7. php xss过滤
  8. 各种oracle参数查询语句
  9. 用 label 控制 Pod 的位置 - 每天5分钟玩转 Docker 容器技术(128)
  10. js实现放大效果
  11. mysql中使用enum,如何获取所有可能的值
  12. vs code 操作Git
  13. 生产与学术之Pytorch模型导出为安卓Apk尝试记录
  14. 第三十节,目标检测算法之Fast R-CNN算法详解
  15. luogu1856
  16. 求web前端面试题库及答案
  17. angular4 辅助路由
  18. 三层架构下实现用户登陆C#
  19. sqlserver查询数据表中每个类别最新的一条记录
  20. [Python] 错误“IndentationError: unindent does not match any outer indentation level”是什么意思?

热门文章

  1. Object.is() Pollyfill
  2. leetcode 19. Remove Nth Node From End of List(链表)
  3. Ubuntu16.04 安装 Visual Studio Code之后启动不起来
  4. bzoj 3653 谈笑风生——主席树
  5. 一般项目转为Maven项目所遇到的问题
  6. 【转】有的共享软件赚了一百万美元,而为什么你没有?&amp;&amp;我的软件推广成功之路
  7. python set集合的用法
  8. The Tomcat server configuration at \Servers\Tomcat v8.0 Server at localhost-config is missing. Check the server for erro
  9. jmp $
  10. java&amp;nbsp;POP3