# 数据类型
while……else…… 和 for……else…… 需要注意的是这里只有内层有break跳出循环才不会执行else的语句
数据类型:
int
、str
、list
、tuple
、dic
、set
、bool
- 可哈希(不可变):数字、字符串、元组、布尔
- 不可哈希(可变):列表、字典、集合
数字
int
:#bit_length() # 当十进制用二进制表示时,有效位数 data = 11.bit_length() print(data) # 3
字符型换
str
:#切片 a='ABCdfsefef' print(a[0:-1]) #-1就是最后一个 取到前一个,即倒数第二个 print(a[0:5:2]) #加步长 C、E print(a[5:0:-2]) #反向加步长 v=a[~3] # 反向,但是索引还是0开始 c=a[~3:2:-1] # 同样的顾头不顾尾 print(v,c) # e esf #常用字符串的方法 print('Acss'.swapcase()) #大小写翻转,大写的小写,小写的大写 print('egon say hi'.title()) #每个单词的首字母大写 print('welcome'.center(20,'=')) #居中,且可以不用设置分隔符 print('Aaaac'.count('a',0,4)) # 可设置开始和结束位置,字符出现的次数 print('Asss\tnice'.expandtabs()) #Asss nice print('adafd'.startswith('ad',0,3)) #True 可设置初始值,默认第一位 同理有endswith() print('asdfadf'.find('df',2,6)) #2 返回第一个位置的索引,可设置初始值,找不到返回-1 print('asdfadf'.index('sd',1,6)) # 1 返回第一个索引,找不到报错 print('adsfsd'.split('s',1)) #['ad', 'fsd'] 从左切割一次,可切割多次 print('adsfsd'.rsplit('s',1)) #['adsf', 'd'] 选择方向 print('*waw**'.strip('*')) # waw ,两边删除 print('wang,niusdf'.replace('wang','SB',1)) # SB,niusdf # 可选择替换次数 print(' '.join(['hi','wang'])) #hi wang 将可迭代对象转化为字符串 #判断系列 print(name.isalnum()) #字符串由字母或数字组成 print(name.isalpha()) #字符串只由字母组成 print(name.isdigit()) #字符串只由数字组成
元组
tuple
:元组被称为只读列表,即数据可以被查询,但不能被修改,所以字符串的切片操作同样适用于元组。例:(1,2,3)("a","b","c")注意:元组中只有一个元素时,需要使用,号隔开如:(3,),否则还是括号里面的数据类型
列表
list
:#增加:append(),insert('index',obj),extend('iterable')、列表还可以使用+号,类似于extend li = [1,'a','b',2,3,'a'] li.insert(0,55) #按照索引去增加 li.append('aaa') #增加到最后 li.append([1,2,3]) #增加到最后,列表嵌套列表 li.extend(['q,a,w']) #迭代的去增 ,括号里面是一个可迭代对象,每一个对象都加进去了 li.extend('abc') #删除:pop(1)、del、 remove('值')、clear() l1 = li.pop(1) #按照位置去删除,有返回值,默认删除尾部,l1,不写索引默认删除最后一个 del li[1:3] #按照位置去删除,也可切片删除没有返回值。 del l1 # 删除整个列表 li.remove('a') #按照元素去删除 注意只有list才有remove,当要删除的对象有多个是,只删除最左的一个,没有报错 #改 li = [1,'a','b',2,3,'a'] li[1] = 'dfasdfas' # 按照相应的索引去改 print(li) #[1, 'dfasdfas', 'b', 2, 3, 'a' li[1:3] = ['a','b'] # 按照切片去改,当有步长的时候必须一一对应,不然报错 print(li) #[1, 'a', 'b', 2, 3, 'a'] li = [1,'we', 32] li.extend(['a','b','c']) # 迭代添加 print(li) #[1, 'we', 32, 'a', 'b', 'c'] li[0:3:2] = ['q','5'] # 当涉及到步长的时候要注意,必须一一对应 print(li) #报错 [1, 'we', 32] --> ['q', '5'] 这里将前面要被取代的位置换为'q','5',多了照换 #查:索引循环 for #其他的方法:count、index、sort、reverse a = ["q","w","q","r","t","y"] print(a.count("q")) # 2 count 统计 某元素出现的次数 print(a.index("r")) #3 index 找出某个值第一个匹配项的索引位置 找不到报错 l = [[1,2],[3,4,5,6],(7,),'123'] print(sorted(l,key=len)) # 注意sorted的占用内存多,key a=[-1,2,4,5] a.sort(key=lambda x:len(str(x))) # 他没有返回值,所以只能打印a,注意列表的sort函数,用法和sorted方法相同, #有key键接受函数名或则lambda,但是s不会生成新列表 print(a) #[2, 4, 5, -1] #列表和元组的烧操作:+ li=[1,3,5,6] print(li+[2,4]) #[1, 3, 5, 6, 2, 4] tu=(2,4,5,4,[1,]) print(tu[-1]+[1,3,5]) #[1, 3, 5, 6, 2, 4] print(tu) #(2, 4, 5, 4, [1])
字典
dict
:字典是python中唯一的映射类型,采用键值对(key-value)的形式存储数据。python对key进行哈希函数运算,根据计算的结果决定value的存储地址,所以字典是无序存储的(自Python3.6后,默认是有序的),且key必须是可哈希的。可哈希表示key必须是不可变类型,如:数字、字符串、元组。#增:键值对,setdefault, dic = {} dic['name'] = '周润发' # 如果dict中没有出现这个key, 就会新增一个key-value的组合进dict ,字典里有则会覆盖 dic['age'] = 18 # 如果dict中没有出现过这个key-value. 可以通过setdefault设置默认值 a=dic.setdefault('李嘉诚') # 也可以往里面设置值.返回None dic.setdefault("李嘉诚", "房地产") # 如果dict中已经存在了. 那setdefault将不会 起作⽤用 ret = dic.setdefault('a','没有a') # 没有返回第二个参数 print(dic,a,ret) #{'name': '周润发', 'age': 18, '李嘉诚': None, 'a': '没有a'} None 没有a #删:pop('key')、del、popitem() ret = dic.pop("jay") # 默认删除最后一个,可根据键删除 del dic["jay"] # 删除含有这个key的键值对 ret = dic.popitem() # 随机删除,但是在3.6中一般是删除最后一个,返回一个元组 dic.clear() # 清空列表 # 改 dic = {"id": 123, "name": 'sylar', "age": 18} dic1 = {"id": 456, "name": "麻花藤", "ok": "wtf"} dic.update(dic1) # 把dic1中的内容更更新到dic中. 如果key重名. 则修改替换. 如果不存 在key, 则新增. print(dic) dic[key] = value # 强行赋值 #查:setdefault、get() ***** dic = {'name':'wang li', 'age':23'} print(dic['name']) # wang li # print(dic['sylar']) # 报错 print(dic.setdefault('name') # setdefault 也可以查取后面的值 又返回值'wang li' print(dic.get("sylar")) # None ,后面没有返回值就返回None print(dic.get("sylar", "⽜B")) # ⽜B,如果在字典里没有找到key则会输出牛B #其他方法: #枚举 enumerate li = ['alex','银角','女神','egon','太白'] for i,v in enumerate(li,1): print(i,v) # 这里输出的是元组,类似于(0, 'alex'),(1, '银角')…… #将a,b的每一项合并 a = ['a,1','b,3,22','c,3,4','f,5',] b=['a,2,1','b,4','d,2','e,12','g,12,43','a,4354,6'] g = { i[0]:i for i in a} for i in b: if i[0] in g: g[i[0]]=g[i[0]][2:]+i[1:] else: g[i[0]]=i print(list(g.values())) #工厂化字典 dic=dict([('name','alex'),('age','12')]) #里面必须是([ ]) print(dic) #{'name': 'alex', 'age': '12'} #setdefault的相关用法 dic = {} dic.setdefault(None,[]).append('1') print(dic) #{None: ['1']} --------字典属性--------- 1.字典是一种可变的容器,可以存储任意类型的数据 2.字典中的每个数据都是用'键'(key)来进行索引的,而不向列表和元组中可以使用整数下标来进行索引 3.字典中的数据是没有先后顺序的,字典的存储是无序的 4.字典中数据以键(key):值(value)对的方式进行存储的 5.字典的键不能重复,且只能用不可变的数据作为字典的键
集合
set
:无序性、互异性、元素可hash#去重 set = {'1', 'wangli', True, [1, 2, 3]} # 报错,元素必须时不可变类型 #集合的增:add、update s = {"刘嘉玲", '关之琳', "王祖贤"} s.add("郑裕玲") print(s) #{'关之琳', '王祖贤', '刘嘉玲', '郑裕玲'} s = {"刘嘉玲", '关之琳', "王祖贤"} s.update("麻花藤") # 迭代更更新 print(s) # {'李若彤', '麻', '张曼⽟', '藤', '花', '王祖贤', '刘嘉玲', '关之琳'} #删:pop()、remove()、clear() s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"} item = s.pop() # 随机弹出一个. print(s) #{'张曼玉', '李若彤', '王祖贤', '关之琳'} print(item) #刘嘉玲 s.remove("关之琳") # 直接删除元素 不存在这个元素. 删除会报错 print(s) #{'张曼玉', '李若彤', '王祖贤'} s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和 dict区分的. print(s) # set() #改:集合没有索引所以不能一个个取,只能remove删了指定元素,再加 #查:可以用for循环 #集合的操作 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)) # {'冯乡长', '刘能', '刘科长', '赵四'} -----集合的一些属性————----- 1.集合是一个可变容器 2.集合内的数据对象都是唯一的(不能重复) 3.集合是无序的存储结构,集合内的数据没有先后关系 4.集合是可迭代对象 5.集合相当于是只有键没有值得字典(键就是集合中的数据) 6.集合内的元素是不可变的 ------创建集合------------- 1.使用直接量创建集合 注意:使用直接量不能创建空集合 s = {1,2,3} s = {"hello",3.14,True,(2019,02,17)} 2.使用构造函数创建集合 - set s = set() #创建空集合 s = set(iterable) #使用可迭代对象创建一个集合 s = set("ABC") # s = {'A','B','C'} s = set([1,0,3.14,"hello"]) # s = {1,0,3.14,'hello'} --------集合的方法---------- add() # 集合对象.add(elem) 向集合内增加元素,如果添加的元素已经存在的话,则不执行任何操作 clear() # 集合对象.clear() 清空集合内所有的元素 copy() # 集合对象.copy() 复制一个集合 difference() # 集合对象1.difference(集合对象2) 返回两个集合的补集 dierence_update() #集合对象1.difference_update(集合对象2) 移除两个集合中都存在的元素 remove() # 集合对象.remove(移除元素) 移除指定的元素 discard() # 同上 pop() #随机删除 update() # s1.update(s2) 用于更新s1集合的新集合 ,修改当前集合,也可以添加新元素到集合中 --------集合推到式----------- L = [1,2,3,4,5,6,7,8,9] s = { x for x in L} s = { x for x in L if x % 2 == 0} --------固定集合------------- 1.frozenset() : 创建一个空的固定集合 2.frozenset(iterable) : 使用可迭代对象创建固定集合
# 深浅拷贝
1.浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)但是第一层虽然拷贝了,但是可以自己直接修改自己的,在第一层中如果存在嵌套地址,那么修改嵌套里面的数据,大家都会改。
2.深拷贝:深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)深拷贝就是完完全全复制了一份,且数据不会互相影响,因为内存不共享。
# 浅拷贝
lst1 = ["何炅", "杜海涛","周渝民"]
lst2 = lst1.copy() # 浅拷贝
lst1.append("李嘉诚") # 互不影响,只拷贝一层壳
print(lst1,lst2,id(lst1), id(lst2)) #['何炅', '杜海涛', '周渝民', '李嘉诚'] ['何炅', '杜海涛', '周渝民'] 47203752 47204912
lst1 = ["何炅", "杜海涛","周渝民", ["麻花藤", "马芸", "周笔畅"]] #第二层有可变类型
lst2 = lst1.copy()
lst1[3].append("无敌是多磨寂寞")
print(id(lst1[3]), id(lst2[3])) #id一致
#深拷贝
import copy
l1 = [1, 2, [11, 22, 33]]
# l2 = copy.copy(l1) 浅拷贝
l2 = copy.deepcopy(l1) #深拷贝
print(l1,'>>>',l2) #[1, 2, [11, 22, 33]] >>> [1, 2, [11, 22, 33]]
l2[2][0] = 1111
print(l1,">>>",l2) #[1, 2, [11, 22, 33]] >>> [1, 2, [1111, 22, 33]]
# 补充个面试题:
a = [1, 2]
a[1] = a
print(a) # 结果: [1, [...]]
# 代码块的缓存机制
Python在执行 同一个代码 块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值
能够提高一些字符串,整数处理人物在时间和空间上的性能;需要值相同的字符串,整数的时候,直接从‘池’里拿来用,避免频繁的创建和销毁,提升效率,节约内存。
int
(float):任何数字在同一代码块下都会复用。bool
:True和False在字典中会以1,0方式存在,并且复用。str
:几乎所有的字符串都会符合缓存机制,具体规定如下(了解即可!)
# 小数据池
- 小数据池,也称为小整数缓存机制,或者称为驻留机制等
- 小数据池也是只针对
int(float),str,bool
,且区别于缓存机制的是:不同代码块 Python自动将**-5~256**的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。 - 优点和缓存机制一致:都是节省内存开销,提升效率
# 文件操作
使⽤Python来读写⽂件是非常简单的操作. 我们使用open()函数来打开一个文件, 获取到⽂件句柄. 然后通过文件句柄就可以进行各种各样的操作了了. 根据打开方式的不同能够执行的操 作也会有相应的差异. 打开文件的方式:
r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b
默认使⽤用的是r(只读)模式注意文件的读写是只针对文件,而不是文件夹,且没有使用文件句柄的时候,要f.close()关闭文件句柄。
在读取或写,非字符串文件时,比如视频、图片,就要使用含'b'的格式
一般格式: f =open(’文件名(路径)', mode='模式',encoding ='编码方式')
特殊格式:with open(’文件名(路径)', mode='模式',encoding ='编码方式') as f:
#读文件:read()将文件的内容全部读取出来, 弊端:相当占内存,如果文件过大,容易导致内存崩溃 f = open("护⼠少妇嫩模.txt",mode="r", encoding="utf-8") content = f.read() # 在这里要记住,在r模式下encoding 表示解码,在w情况下,是编码 print(content) f.close() #关闭文件句柄 #readline() ⼀次读取⼀行数据, 注意: readline()结尾, 注意每次读取出来的数据都会有⼀ 个\n 所以呢. 需 要我们使⽤用strip()⽅方法来去掉\n或者空格 #readline(n) 当有参数n时,则时读取一行的开头的前n个字符: #readlines() 将每一⾏形成一个元素, 放到⼀个列表中. 将所有的内容都读取出来. 所以 也是. 容易易出现内 存崩溃的问题.不推荐使⽤,形成一个列表 from collections import Iterable,Iterator print(isinstance(open('a','w'),Iterable)) #True print(isinstance(open('a','w'),Iterator)) # True 所以文件句柄是个可迭代的,迭代器 #写模式:写的时候注意. 如果没有文件. 则会创建文件, 如果⽂件存在. 则将原件中原来的内容删除, 再写入新内容 f = open("⼩小娃娃", mode="w", encoding="utf-8") f.write("⾦⽑狮王") f.flush() # 刷新. 养成好习惯 f.close() #追加:在追加模式下. 我们写入的内容会追加在⽂件的结尾,相当于在这种模式下,打开后光标默认在尾部. f = open("⼩小娃娃", mode="a", encoding="utf-8") f.write("麻花藤的最爱") f.flush() f.close() # 正常的读取之后, 写在结尾 #重要的其他方法: #seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的中⽂部要是3的倍数. 通常我们使用seek都是移动到开头或者结尾。 移动到开头: seek(0) 移动到结尾: seek(0,2) # tell() 使⽤用tell()可以帮我们获取到当前光标在什么位置,应该是自己的bytes # truncate() 截断⽂件 使用的是光标 f = open("⼩娃娃", mode="w", encoding="utf-8") f.write("哈哈") # 写入两个字符 f.seek(3) # 光标移动到3, 也就是两个字中间 f.truncate() # 删掉光标后⾯面的所有内容 f.close()