第十一章:内置函数与异常处理

内置函数

重要内置函数

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
posted @ 2022-10-18 01:10  亦双弓  阅读(167)  评论(0)    收藏  举报