python-生成器和常见内置函数
异常捕获(二)
try:
name
except Exception as e:
print("代码错误")
else:
print('代码正常才会执行了')
finally:
print('代码不管是否异常都会运行')
# 断言
name = 'jason'
assert isinstance(name, str)
# 主动抛出异常
raise ZeroDivisionError('除数不能为0')
for 循环本质
d = {'name': 'jason', 'age': 18}
res = d.__iter__() # StopIteration的异常,该异常是在循环对象穷尽所有元素时的报错
# while实现循环打印
while True:
try:
print(res.__next__())
except StopIteration as e:
break
# for循环打印
for i in d:
print(i)
迭代取值与索引取值对比
迭代取值
- 不依赖索引进行取值
- 取值的顺序都是固定的从左到右,无法重复获取
索引取值
- 可以重复取值
- 需要提供有序容器类型才可取值(不是通用方式)
生成器对象
生成器其实就是自定义迭代器
# 定义阶段就是一个普通函数
def my_generator():
print('first')
yield 11
print('second')
yield 22
"""
当函数体内含有yield关键字 那么在第一次调用函数的时候
并不会执行函数体代码 而是将函数变成了生成器(迭代器)
"""
res = my_generator() # 调用函数不执行函数体代码,而是将函数变成生成器(迭代器)
print(res) # <generator object my_generator at 0x7fcc5f7d3888>
ret = res.__next__() # 每执行一个__next__代码往下运行到yield停止 返回后面的数据
print(ret) # first \n 11
ret = res.__next__() # 再次执行__next__接着上次停止的地方继续往后 遇到yield再停止
print(ret) # second \n 22
自定义 range 功能
def my_range(start, stop=None, step=1):
if not stop:
stop, start = start, 0
while start < stop:
yield start
start += step
for i in my_range(2, 10, 2):
print(i)
yield 传值
def generator_func1(age):
print('age is %s ' % age)
while True:
name = yield
print('%s NB' % name)
res = generator_func1(18) # 不会执行函数体代码,而是转换成生成器
res.__next__()
res.send('json') # 给yield传值
res.send('xxx') # 再次给yield传值
yeild 与 return 对比
相同点:可以返回值,支持多个并且组织成元组
不同点:
yield:
1. 函数体代码遇到yield不会结束,会'停住'
2. yield可以将函数变成生成器,并且支持外界传值
return:
1. 函数体代码遇到return直接结束
生成器表达式
# 列表生成式
l1 = [11, 22, 33, 44, 55, 66]
res = [i + 1 for i in l1 if i != 44]
print(res) # [12, 23, 34, 56, 67]
# 生成器表达式
'''生成器表达式内部的代码只有在迭代取值的时候才会执行'''
res1 = (i + 1 for i in l1 if i != 44)
print(res1) # <generator object <genexpr> at 0x7fbbb7e96ca8>
print(res1.__next__()) # 12
print(res1.__next__()) # 23
print(res1.__next__()) # 24
笔试题
# 求和 def add(n, i): return n + i # 调用之前是函数 调用之后是生成器 def test(): for i in range(4): yield i g = test() # 初始化生成器对象 for n in [1, 10]: g = (add(n, i) for i in g) """ 第一次for循环 g = (add(n, i) for i in g) 第二次for循环 g = (add(10, i) for i in (add(10, i) for i in g)) """ res = list(g) print(res) #A. res=[10,11,12,13] #B. res=[11,12,13,14] C. res=[20,21,22,23] #D. res=[21,22,23,24]
常见内置函数
1. abs() # 取绝对值
print(abs(-10)) # 10
2. all() any()
l = [11, 22, 0]
print(all(l)) # 所有元素为True才是True
print(any(l)) # 所有元素有一个为True就是True
3. bin() oct() hex()
print(bin(12)) # 0b1100 二进制
print(oct(12)) # 0o14 八进制
print(hex(12)) # 0xc 十六进制
4. bytes() str()
res = '测试'
ret1 = bytes(res, 'utf8')
print(ret1) # b'\xe6\xb5\x8b\xe8\xaf\x95'
ret2 = str(ret1, 'utf8')
print(ret2) # 测试
5. callable() # 是否看调用(看是否能加括号运行)
i = 1
def f():
pass
print(callable(i), callable(f)) # Flse True
6. chr() ord()
print(chr(65)) # A 按照ASICC码表的数字打印字符
print(ord('A')) # 65 按照ASICC码表的字符打印数字
7. complex() 复数
print(complex(123)) # (123+0j)
8. dir() # 查看当前对象可以调用的名字
def f():
pass
print(dir(f))
9. divmod() # 接收两个数字类型参数,返回一个包含商和余数的元组(a // b, a % b)
print(divmod(101, 10)) # (10 1)
应用:
# 生成页数
num, more = divmod(201, 10)
if more:
num += 1
print('总共需要%s页' % num)
10. eval() exec() # 将字符串内的内容加载执行
s1 = "print('hello')"
s2 = '''
for i in range(10):
print(i)
'''
eval(s1) # 只能执行简单的内容
exec(s2) # 可以执行复杂的内容
11. isinstance() # 判断是否属于某个数据类型
i = 1
print(isinstance(i, int)) # True
12. pow()
print(pow(4, 3)) # 64 4**3
13. round()
print(round(4.5)) # 4
print(round(4.6)) # 5
14. sum() # 求和
l = [11, 22, 33, 44]
print(sum(l)) # 110 将列表 l 中的元素求和