python-生成器和常见内置函数

异常捕获(二)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try:
name
except Exception as e:
print("代码错误")
else:
print('代码正常才会执行了')
finally:
print('代码不管是否异常都会运行')

# 断言
name = 'jason'
assert isinstance(name, str)

# 主动抛出异常
raise ZeroDivisionError('除数不能为0')

for循环本质

1
2
3
4
5
6
7
8
9
10
11
12
13
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)

迭代取值与索引取值对比

  • 迭代取值

    1. 不依赖索引进行取值
    2. 取值的顺序都是固定的从左到右,无法重复获取
  • 索引取值

    1. 可以重复取值
    2. 需要提供有序容器类型才可取值(不是通用方式)

生成器对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
生成器其实就是自定义迭代器

# 定义阶段就是一个普通函数
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功能

1
2
3
4
5
6
7
8
9
10
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传值

1
2
3
4
5
6
7
8
9
10
11
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对比

1
2
3
4
5
6
7
相同点:可以返回值,支持多个并且组织成元组
不同点:
yield:
1. 函数体代码遇到yield不会结束,会'停住'
2. yield可以将函数变成生成器,并且支持外界传值
return:
1. 函数体代码遇到return直接结束

生成器表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
# 列表生成式
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
  • 笔试题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 求和
    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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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 中的元素求和