【第13天】Python第一阶段学习总结
2021/09/30
一. 迭代器
1. 什么是迭代器(iter)
-
迭代器是容器型数据类型
-
创建迭代器:
- 将其他序列转换成迭代器
- 创建生成器
-
特点:
- 打印不能查看到迭代器中的元素
- 不能通过len获取迭代器中元素的个数
- 如果要使用元素必须将元素从迭代器中取出,而且取出后无法放回
-
**重要结论:**不管用任何方式获取到了迭代器中的元素,那么被取到的元素一定会从迭代器中消失
i1 = iter('abc') print(i1) # <str_iterator object at 0x00000239D79D5580> # print(len(i1)) # TypeError: object of type 'str_iterator' has no len() i2 = iter([10, 20, 30, 40]) print(i2) # <list_iterator object at 0x00000239D79D5B50>
2. 获取元素
-
获取单个元素(最上面的元素):next(迭代器)
i1 = iter('abc') print(next(i1)) # a print(next(i1)) # b print(next(i1)) # c # print(next(i1)) # 报错! StopIteration # 重要结论:不管用任何方式获取到了迭代器中的元素,那么被取到的元素一定会从迭代器中消失
i2 = iter([10, 20, 30, 40]) print(list(i2)) # [20, 30, 40] # print(next(i2)) # 报错! StopIteration
i3 = iter((10, 'abc', 20, False)) for x in i3: print(x) # print(next(i3)) # StopIteration print(list(i3)) # []
二. 生成器
1. 什么是生成器 - generator
- 生成器是一种容器:是一种特殊的迭代器(具备迭代器的特点)
2. 怎么创建生成器
-
调用带有yield关键字的函数就可以得到一个生成器。
-
调用普通函数会执行函数体,并且获取函数返回值(函数调用表达式的值就是函数的返回值);如果被调用的函数中有yield,那么调用函数的时候不会执行函数体,也不会获取函数返回值,函数调用表达式的值是一个生成器对象
def func1(): print('函数') yield return 100 result = func1() print(f'result:{result}') # result:100 print(f'result:{result}') # result:<generator object func1 at 0x000002648180A740>
-
控制生成器元素的个数和元素:调用函数创建的生成器中有多少个元素,每个元素是什么由执行完函数体会遇到几次yield以及每次遇到yield的时候后面的数据决定
def func2(): yield 100 yield 200 yield 300 if False: yield 400 for x in range(3): yield 100+x gen1 = func2() print(gen1) print(list(gen1)) # next(gen1) # next(gen1) # StopIteration
# 练习:创建一个生成器,可以创建的数据:'py001',....'py100' def id(subject): for x in range(1, 101): yield f'{subject}{x:0>3}' gen3 = id('python') gen4 = id('java') print(next(gen3)) print(next(gen4)) print(next(gen3)) print(next(gen3))
def func3(): print('++++++++') yield 10 print('--------') yield 20 print('========') yield 30 print('end!') gen3 = func3() print('第1个:') print(next(gen3)) # 10 print('第2个:') print(next(gen3)) # 20 print('第3个:') print(next(gen3)) # 30 print('第4个:') # print(next(gen3)) # 会打印end! 但是会报错StopIteration
def func4(): yield 111 yield 222 yield 333 # 每次调用新的生成器,每次只生成一个元素 print(next(func4())) # 111 print(next(func4())) # 111 # 只调用一次生成器,每次从生成器中生成一个元素 gen = func4() print(next(gen)) # 111 print(next(gen)) # 222
# 练习:写一个创建一副扑克牌的生成器 # 花色:黑桃♠,梅花♣,红桃♥,方片♦ # 数字:2-10, A, J, Q, K types = '♠♥♣♦' nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] def poker(str1: str, list1: list): for type in str1: for num in list1: yield type + num gen1 = poker(types, nums) print(list(gen1)) # print(next(gen1)) # ♠A # print(next(gen1)) # ♠2 # print(next(gen1)) # ♠3 # print(next(gen1)) # ♠4 # print(next(gen1)) # ♠5 from random import shuffle, choice, choices def get_poker(): nums = [str(x) for x in range(2, 11)] + list('JQKA') colors = '♠♥♣♦' for num in nums: for color in colors: yield color + num yield 'JOKER' yield 'joker' gen1 = get_poker() pokers = list(gen1) # 洗牌(随机打乱列表中的元素顺序) shuffle(pokers) print(pokers) # 随机选择 print(choice(pokers)) print(choices(pokers, k=3))