Python 知识点
python 知识点
判断字符串是否是纯数字:isdigit()
name = '123'
if name.isdigit():
print("是数字")
else:
exit("不是数字") # exit()退出程序
枚举列表:enumerate()
把列表的元素列举出来
a = [12,23,45,56]
for i,v in enumerate(a):
print(i,v)
# 输出结果
1 12
2 23
3 45
4 56
in 和 not in 成员运算符
print("egon" in "hello egon") 判断一个字符串是否存在于一个大字符串里
print(111 in [111,222,333]) 判断元素是否存在于列表
print("k1" in {"k1":111,"k2":222}) 判断key是否存在于字典里
print("egon" not in "hello egon") 判断一个字符串是否不存在于一个大字符串里
is 身份运算符与==的区别
is 判断id(内存地址)是否相等
== 判断值是否相等
深浅拷贝 copy
需求:
1)拷贝一下原来列表产生一个新列表
2)想让两个列表完全独立开,针对的是改操作的独立而不是读操作
# 浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)
list1 = ['egon','lxx',[1,2]]
list2 = list1.copy()
print(list2)
# 深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)
import copy
list1 = ['egon','lxx',[1,2]]
list2 = copy.deepcopy(list1)
# 深copy对不可变与可变加与区分
strip() 去除字符串左右两侧的符号
默认去除空格
只去两边不去中间
msg = '***e****gon***'
print(msg.strip('*'))
# 输出结果
'e****gon'
切分split()
把一个字符串按照某种分隔符进行切分,得到一个列表
默认分隔符是空格
- num 参数:分割次数,默认-1所有。
info = 'hp 18 male'
res = info.split()
print(res)
# 输出结果
['hp','18','male']
拼接 join()
将列表拼接成字符串
l = ['hp','18','male']
res = ":".join(l) # 按照某个分隔符,把元素全为字符串的列表拼接成一个大字符串
print(res)
# 输出结果
'hp:18:male'
替换字符串replace
info = 'hp hp 18 male'
print(info.replace("hp","HP",1))# 替换前的子串,替换后的字符串,替换次数(不写,找到相同的全部替换)
# 输出结果
'HP hp 18 male'
字符串查找索引:find, index
info = 'hp hp 18 male'
print(info.find('h')) # 返回要查找的字符串在大字符中的起始索引值
print(info.index('p'))
find与index的区别:
find找不到要查找的字符串返回-1
index找不到要查找的字符串抛出异常
统计字符串个数 count
info = 'hp hp 18 male'
print(info.count("h"))
# 输出结果
2
列表删除
1. l.del() # 通用删除方法,单纯删除没有返回值
2. l.pop() # 根据索引删除,会返回删除值,不指定索引默认删除最后一个
3. l.remove() # 根据元素删除,返回None
[].sort() 列表排序
列表内的元素必须是同种类型才可以排序
[].sort() # 默认从小到大排序,升序
[].sort(reverse = True) # 降序
快速初始化字典 {}.fromkeys()
keys = ["name","age","gender"]
d = {}.fromkeys(keys,None)
# 输出结果
{"name":None,"age":None,"gender":None}
更新字典 .update()
d = {'k1':111}
d.updata({'k2':222,'k3':333,'k1':1111})
# 输出结果
{'k1':1111,'k2':222,'k3':333}
# 添加不存在的,修改已存在的
setdefault()
如果key存在则不添加,返回字典可以对应的值
如果key不存在则添加,返回字典可以对应的值
文件使用 open()
控制文件读写内容模式:t 和 b
强调:t 和 b不能单独使用,必须跟 r/w/a 连用
t 文本 (默认的模式)
- 读写都以str (unicode)为单位
- 只能读文本文件
- 必须指定字符编码
encoding = 'utf-8'
b 二进制/ bytes
- 读写都是以bytes为单位
- 可以针对所以文件
- 一定不能指定字符编码
读取文本内容
readline()
:一次读一行read()
:全部读取readlines()
:全部读取,读取的一行一行内容放到列表显示
强调:read()
和 readlines()
都是将内容一次性读入内存,如果内容过大会导致内存溢出。若还想将内容全部读入内存,则必须分多次读入,两种方式:for循环 或 while循环
文件指针移动
指针移动单位都是以bytes/字节为单位
特殊情况:t 模式下的 read(n)
,n代表的是字符个数
f.tell()
获取文件指针当前位置
f.seek(n,模式):n指的是移动的字节个数
模式:
0:参照物是文件开头位置
f.seek(9,0)
1:参照物是当前指针所在位置
f.seek(9,1)
2:参照物是文件末尾位置,应该倒着移动
f.seek(-9,2)
强调:只有 0模式 可以在t下使用,1、2必须在b模式下使用
修改文本文件
方式一:文本编译采用的方式
浪费内存空间
c.txt内容:
alex is sb
sb is alex
engo is hahahhaha
with open('c.txt',mmode='rt',encoding='utf-8') as f:
res = read()
data = replace('alex','dsb') # 代替
print(data)
with open('c.txt',mmode='wt',encoding='utf-8') as f1:
f1.write(data)
# 修改结果
dsb is sb
sb is dsb
engo is hahahhaha
方式二:
浪费硬盘空间
import os
with open('c.txt',mmode='rt',encoding='utf-8') as f,\
open('.c.txt.swap',mmode='wt',encoding='utf-8') as f1:
for line f: # for循环,读取内容,节省内存空间
f1.write(f.replace('alex','dsb'))
os.remove('c.txt') # 删除原文件
os.rename('.c.txt.swap','c.txt') # 修改新文件名
yield的表达式
yield可以控制函数的停止,也可以当做返回值与return的用法相似
yield可以用作表达式,通过.send()
为yield传值
def test(name):
print('%s程序运行到第一行'%name)
while True:
# x 拿到的是yield接收到的值
x = yield
print('%s程序运行到最后拿到的值:%s'%(name,x))
g = test('测试') # 因为yield关键字,使得函数成为生成器对象
g.send(None) # 等同于 next(g) ,会触发函数体代码运行,然后遇到yield停下来
g.send('11111') # 为yield传值
三元表达式
语法格式:条件成立返回的值 if 条件 else 条件不成立返回的值
比较两个值大小
#函数写法
def res(x,y):
if x > y:
return x
else:
return y
#三元表达式写法
res = x if x > y else y
列表生成器
#普通写法
l = ['abs_dsb','zxc_dsb','aer_dsb','ssss']
new_l = []
for name in l:
if name.endswith('dsb'): # endswith以什么结尾
new_l.append(name)
#列表生成器写法
l = ['abs_dsb','zxc_dsb','aer_dsb','ssss']
new_l = [name for name in l if name.endswith('dsb')]
函数的递归调用
函数的递归调用就是函数直接或间接的调用自己
递归的两个阶段
回溯:一层一层调用下去
递推:满足某种结束条件,结束递归调用,然后一层一层返回
例子:问年龄
#arg(5) = arg(4) + 10
#arg(4) = arg(3) + 10
#arg(3) = arg(2) + 10
#arg(2) = arg(1) + 10
#arg(1) = 18
def arg(n):
if n == 1:
arg(1) == 18
else:
res = arg(n-1) + 10
return res
算法之二分法
二分法取值,通过对中间值对比,找的值比中间值大,则舍去左半,与右半的中间值在对比。
l = [-3,4,7,10,16,21,30,45,64,78]
find_num = 10
def binary_search(find_num,l):
print(l)
if l(1) == 0:
ptint('找的值不存在')
return
#mid_val = 找列表中间的值
mid_index = len(l) // 2
mid_val = l[mid_index]
if find_num > mid_val:
#查找应该再列表的右半部分
l = l[mid_index + 1 :] #列表切片右半部分
binary_search(find_num,l)
elif find_num < mid_val:
#查找应该再列表的左半部分
l = l[:mid_index] #列表切片左半部分
binary_search(find_num,l)
else:
print('find it')
binary_search(find_num,l)
匿名函数
对比使用def关键字创建的是有名字的函数,使用lambda
创建的是匿名函数
语法如下:
lambda 参数1,参数2,...: expression
举例:
#定义:
lambda x,y,z:x+y+z
#调用
#方式一:
res = (lambda x,y,z:x+y+z)(1,2,3)
print(res)
#方式二:
func = lambda x,y,z:x+y+z
res = func(1,2,3)
print(res)
匿名函数因为没有名字,所以调用一次后就会被回收
匿名函数用于临时调用一次的场景
包
包就是一个包含有__init__.py
文件的文件夹。
包的本质就是模块的一种形式,包是用来被当做模块导入。
创建一个文件夹名字为mmm
,文件夹里面放__init__.py
文件
mmm/ #顶级包
|---__init__.py
|---futures #子包
| |---__init__.py
| |---process.py
|---test.py
导入包的过程
- 产生一个名称空间
- 运行包下的
__init__.py
文件,将运行过程产生的名字都丢到1产生的名称空间中 - 当前执行文件的名称空间中拿到一个名字
mmm
,mmm
指向1的名称空间
强调
- 无论导入语句是import 或是 from ... import ... ,在导入是必须遵守一个原则:凡是在导入时带点的,点的左边必须是一个包,否则非法。
from a.b.c.d import xxx
import a.b.c.d
其中a、b、c都必须是包
- 包A和包B下有同名模块也不会冲突,如A.a与B.a来自两个命名空间
进度条
进度条效果
[# ]
[## ]
[### ]
指定宽度
print('[%-15s]'%'#') # -左对齐,指定宽度为15,传值为%s
print('[%-15s]'%'##')
print('[%-15s]'%'###')
实现
import time
res = ''
for i range(15):
res += '#'
time.sleep(0.5)
print('\r[%-15s]'%res,end='') # end = ''不换行打印,\r行首打印
例子:模拟下载速度,打印进度条
import tiem
def progress(percent):
if percent > 1:
percent = 1
res = int(15 * percent) * '#' # 指定进度条为15,计算多少个#
print('\r[%-15s] %d%%'%(res,int(100 * percent)),end='')
recv_size = 0 # 当前下载
total_size = 333333 # 总下载
while recv_size < total_size:
time.sleep(0.3) # 延迟,模拟网速,下载1024个字节的数据
recv_size += 1024
#打印进度条
percent = recv_size / total_size #获取百分之
progress(percent)