迭代器和生成器

1、生成器与yield

1.1 创建生成器的第一种方式

 如果函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值也就是生成器对象

def my_range(start, stop, step=1):
    print('start...')
    while start < stop:
        yield start
        start += step
    print('end...')


g = my_range(0, 5)
print(g)

输出结果:

<generator object my_range at 0x000002549A231E00>

1.2 生成器的本质就是一个迭代器

生成器内置有__iter__和__next__方法,所以生成器本身就是一个迭代器

def my_range(start, stop, step=1):
    print('start...')
    while start < stop:
        yield start
        start += step
    print('end...')


g = my_range(0, 5)
print(g.__next__())  # 触发函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
print(g.__next__())  # 再次调用,函数从上次暂停的位置继续执行,直到遇到新的yield
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())  # 触发函数执行没有遇到yield则没有值返回,即取值完毕抛出异常结束迭代

输出:

Traceback (most recent call last):
  File "D:\python\基础\迭代.py", line 15, in <module>
    print(g.__next__())
StopIteration
start...
0
1
2
3
4
end...

Process finished with exit code 1

2、yield表达式应用

def eater():
    print('ready to eat...')
    while True:
        food = yield
        print(f'eat the food {food} and start to eat ...')


g = eater()  # 得到生成器对象
g.__next__()  # 初始化,让函数挂起在food = yield ,等待调用g.send()方法传值
g.send('food1')
g.send('food2')

输出:

ready to eat...
eat the food food1 and start to eat ...
eat the food food2 and start to eat ...

表达式形式的yield也可以用于返回多次值,即变量名 = yield 值的形式,如下代码

def eater():
    print('ready to eat...')
    food_list = []
    while True:
        food = yield food_list
        food_list.append(food)
        print(food_list)


g = eater()  # 得到生成器对象
g.__next__()  # 初始化,让函数挂起在food = yield ,等待调用g.send()方法传值
g.send('food1')
g.send('food2')

输出:

ready to eat...
['food1']
['food1', 'food2']

3、三元表达式

res = 条件成立时候的返回值 if 条件 else 条件不成立的时候的返回值

x = 1
y = 2

res = x if x > y else y
print(res)

4、列表生成式

[expression for item1 in iterable1 if condition1

for item2 in interable2 if condition2]

egg_list = []
for i in range(10):
    egg_list.append(f'egg{i}')
print(egg_list)

相当于

print([f'egg{i}' for i in range(10)])

5、生成器表达式

创建生成器的第二种方法:

创建一个生成器对象,一种是调用yield关键字函数,另一种就是生成器表达式,与列表生成器的语法格式相同,只需要将[ ]换成( )也就是:

(expression for item in iterable if condition)

对比列表生成器返回的是一个列表,生成器表达式返回的是一个生成器对象

print([i ** 2 for i in range(10)])
print((i ** 2 for i in range(10)))

输出:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x000001D03FBD2030>

对比列表生成式,生成器表达式的优点是节省了内存(一次值产生一个值在内存中)

6、生成式

6.1 列表生成式

print([i for i in range(10) if i > 2])

6.2 字典生成式

lst = ['张三', '李四', '王五']
dict1 = {i + 1: lst[i] for i in range(0, len(lst))}

 

posted @ 2022-04-28 17:57  Tatataaa  阅读(42)  评论(0)    收藏  举报