第十一章:内置函数与异常处理
内置函数
重要内置函数
zip 拉链方法
拉链方法 返回的是一个迭代器
木桶短板原则来拉链
# 数量不对等的情况
l = [1, 2, 3, 4, 5]
l2 = ['a', 'b', 'c', 'd']
l3 = ('*', '**', [1, 2])
d = {'k1': 1, 'k2': 2}
for i in zip(l, l2, l3, d):
print(i)
# (1, 'a', '*', 'k2')
# (2, 'b', '**', 'k1')
# 数量对等的情况
l1 = [11, 22, 33, 44, 55]
l2 = ['jason', 'kevin', 'oscar', 'jerry', 'tony']
l3 = [1, 2, 3, 4, 5]
res = zip(l1, l2, l3)
print(list(res)) # [(11, 'jason', 1), (22, 'kevin', 2), (33, 'oscar', 3), (44, 'jerry', 4), (55, 'tony', 5)]
filter 过滤
filter() 函数接收一个函数 f 和一个 list,这个函数 f 的作用是对每个元素进行判断,返回 True 或 False,filter() 根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新 list
l1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = filter(lambda x: x > 40, l1)
print(list(res)) # [44, 55, 66, 77, 88]
# 返回奇数
def is_odd(x):
return x % 2 == 1
ret = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(ret)) # [1, 3, 5, 7, 9]
sorted 排序
sorted 使用场景:列表数据不大,且还要保留原有列表顺序的时候
因为 sorted 排序不改变原有列表,所以在内存空间就会有两个列表
# 从小到大进行排序
k = [1,-4,6,5,-10]
k.sort(key = abs) # sort 在原列表的基础上进行排序
print(k) # [1, -4, 5, 6, -10]
# reverse=True 从大到小排序 reverse=False 从小到大排序(默认)
print(sorted(k,key=abs,reverse=True)) #sorted 生成了一个新列表 不改变原列表 占内存
print(k) # [-10, 6, 5, -4, 1]
# 根据列表中每一个元素的长度进行排序
h = [' ',[1,2],'hello world']
print(sorted(h,key=len)) # [[1, 2], ' ', 'hello world']
map() 映射
map 函数应用于每一个可迭代的项,返回的是一个结果 list。如果有其他的可迭代参数传进来,map 函数则会把每一个参数都以相应的处理函数进行迭代处理。
map() 函数接收两个参数,一个是函数,一个是序列,map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 list 返回。
l1 = [1, 2, 3, 4, 5]
res = map(lambda x: x + 1, l1)
print(list(res)) # [2, 3, 4, 5, 6]
常见内置函数
1、abs() 绝对值
print(abs(1100)) # 1100
print(abs(-1100)) # 1100
2、all()
所有数据值对应的布尔值为 True 结果才是 True 否则返回 False
describe = '1港元兑0.1274美元'
not_cha = ['人', '美', '香港', '日币', '港仙']
is_tf = all(x not in describe for x in not_cha)
print(is_tf) # False
3、any()
所有数据值对应的布尔值有一个为 True 结果就是 True 否则返回 False
describe = '1港元兑0.1274美元'
not_cha = ['人', '美', '香港', '日币', '港仙']
is_tf = any(x not in describe for x in not_cha)
print(is_tf) # True
4、bin() oct() hex() int()
进制 | 进制前缀 | 转为十进制 | 十进制转X进制 | 字符串转值 |
---|---|---|---|---|
二进制 | 0b | int(0b1100100) | bin(100) | int("0b1100100", 2) |
八进制 | 0o | int(0o144) | oct(100) | int("0o144", 8) |
十六进制 | 0x | int(0x64) | hex(100) | int("0x64", 16) |
5、bytes()
转换成 bytes 类型
byte = b"byte example"
str_info = "str example"
# str to bytes 字符串转为字节
ret_b = str.encode(str_info)
print(type(ret_b), ret_b) # <class 'bytes'> b'str example'
# bytes to str 字节转为字符串
ret_str = bytes.decode(byte)
print(type(ret_str), ret_str) # <class 'str'> byte example
6、callable()
判断名字是否可以加括号调用
name = 'jason'
def index():
print('from index')
print(callable(name)) # False
print(callable(index)) # True
7、chr() ord()
基于 ASCII 码表做数字与字母的转换
print(chr(65)) # A
print(ord('A')) # 65
8、dir()
返回括号内对象能够调用的名字
print(dir('hello')) # ['__add__', '__class__', '__contains__' ...]
9、divmod()
返回一个元组:第一个数据为整除数、第二个是余数
res = divmod(500, 2)
print(res) # (250, 0)
res = divmod(100, 3)
print(res) # (33, 1)
10、enumerate() 枚举
lit = ['12', 213, 123, '1234']
for num, val in enumerate(lit):
print(num, val)
# 0 12
# 1 213
# 2 123
# 3 1234
11、eval() exec()
能够识别字符串中的 python 并执行
s1 = 'print("哈哈哈")'
eval(s1) # 哈哈哈
exec(s1) # 哈哈哈
s2 = 'for i in range(100):print(i)'
# eval(s2) # 报错,只能识别简单的 python 代码 具有逻辑性的都不行
exec(s2) # 可执行,可以识别具有一定逻辑性的 python 代码
# 识别字符串格式的 list dict 类型
lit_str = '[12,32432,2,3,243]'
dit_str = "{'age':12,'name': 'ysg'}"
ev_lit = eval(lit_str)
print(type(ev_lit), ev_lit) # <class 'list'> [12, 32432, 2, 3, 243]
ex_lit = exec(lit_str)
print(type(ex_lit), ex_lit) #<class 'NoneType'> None
ev_dit = eval(dit_str)
print(type(ev_dit), ev_dit) # <class 'dict'> {'name': 'ysg', 'age': 12}
ex_dit = exec(dit_str)
print(type(ex_dit), ex_dit) # <class 'NoneType'> None
12、hash()
print(hash('jason'))
13、id()
print(id('123'))
14、max() min()
# 用普通函数的写法
dic={'k1':10,'k2':100,'k3':30}
def func(key):
return dic[key]
print(max(dic,key=func)) # k2 根据返回值判断最大值,返回值最大的那个参数是结果
#匿名函数的写法
print(min(dic,key=lambda k:dic[k])) # k1
15、open()
f = open('E:/py/log/test.txt') # 打开一个文件
print(f.writable()) # 可以使用 writable() 检测一下文件是否可以写
print(f.readable()) # 可以使用 readable() 检测一下文件是否可以读
16、pow() 幂指数(次方)
print(pow(2,3)) # 8 pow幂运算 == 2**3
print(pow(3,2)) # 9
print(pow(2,3,3)) # 2 幂运算之后再取余
print(pow(3,2,1)) # 0
17、range()
range() 的值是可以迭代的,但不是一个迭代器
range(10)
range(1,11)
range(1,11,2)
print('__next__' in dir(range(1,11,2))) # False
print('__next__' in dir(iter(range(1,11,2)))) # True 当它调用 iter() 转换后,就是一个迭代器了
18、round() 四舍五入
# 不精准的四舍五入
print(round(98.3)) # 98
print(round(98.5)) # 98
print(round(98.6)) # 99
def sswr(num, floats):
'''
:param num: 需要四舍五入的数字
:param floats: 小数点后精确位数
:return: 处理后的数值
'''
num1 = float(num * float(10 ** floats))
num2 = int(num * float(10 ** floats))
if int((num1 - num2) * 10) < 5:
val = float(num2 / float(10 ** floats))
return val
elif int((num1 - num2) * 10) >= 5:
val = float(num2 / float(10 ** floats) + float(0.1 ** floats))
return val
ret = sswr(96.22545548, 5)
print(ret) # 96.22546
ret = sswr(96.22545548, 7)
print(ret) # 96.2254555
19、sum()
print(sum([11, 22, 33, 44, 55, 66])) # 231
20、reduce()
reduce() 函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
from functools import reduce
# 方法一
lit = [11, 22, 33]
print(11 * 22 * 33) # 7986
res = reduce(lambda a, b: a * b, lit)
print('res', res) # 7986
# 方法二
def add(x, y):
return x + y
ret = reduce(add, [11, 22, 33])
print(ret) # 66
for循环的本质
for 变量名 in 可迭代对象:
循环体代码
"""
1.先将in后面的数据调用__iter__转变成迭代器对象
2.依次让迭代器对象调用__next__取值
3.一旦__next__取不到值报错 for循环会自动捕获并处理
"""
异常捕获/处理
1.异常
异常就是代码运行报错 行业俗语叫 bug
代码运行中一旦遇到异常会直接结束整个程序的运行 我们在编写代码的过程中药尽可能避免
2.异常分类
语法错误
不允许出现 一旦出现立刻改正 否则提桶跑路
逻辑错误
允许出现的 因为它一眼发现不了 代码运行之后才可能会出现
3.异常结构
错误位置
错误类型
错误详情
4.常见类型
SyntaxError
NameError
IndexError
KeyError
IndentationError
......
异常处理语法
try:
print('代码逻辑')
# name
except NameError as e: # 遇到指定也尝试才被捕捉
print('错误信息为:{}'.format(e))
except Exception as e1: # 万能异常
print('错误信息为:{}'.format(e1))
except BaseException as e2: # 万能异常
print('错误信息为:{}'.format(e2))
# finally:
# print('无论结果如何,都执行')
else:
print('不报错,则执行')
异常处理补充
# 断言
name = 'jason'
# assert isinstance(name, int) # 为 FALSE 就抛异常,下面的代码将不会执行
assert isinstance(name, str)
print('哈哈哈 我就说吧 肯定是字符串')
# 主动抛异常
name = 'ysg'
if name == 'ysg':
raise Exception('老子不干了') # 运行到此行,直接抛出异常:Exception: 老子不干了
else:
print('正常走')
异常处理的实际运用
1.异常处理能尽量少用就少用
2.被 try 监测的代码能尽量少就尽量少
3.当代码中可能会出现一些无法控制的情况报错才应该考虑使用
eg: 使用手机访问网络软件 断网
编写网络爬虫程序请求数据 断网
练习:使用 while 循环 + 异常处理 + 迭代器对象,完成 for 循环迭代取值的功能
lit = [11, 22, 33, 44, 55, 66, 77, 88, 99]
iter_lit = lit.__iter__()
while 1:
try:
print(iter_lit.__next__()) # 错误类型:StopIteration
except Exception as e:
break