同步与异步
# 同步:指的是一个顺序,排队,表现:等待and阻塞;
# 异步:不讲究是否顺序,不排队,表现:不等待and不阻塞
迭代器
定义:iterator,实现迭代器协议的对象;
迭代器协议:__iter__
与 __next__
;
魔术方法代表协议,与java中interface类似
实例
通过迭代器实现生成指定位置的斐波那契数
斐波那契数列(兔子数列、黄金分割数列[(n-1)/n=0.618])
1,2,3,5,8,13,21,…
code
class FibNums:
def __init__(self, num):
self.a, self.b = 0, 1
self.count = 0
self.num = num
def __iter__(self):
return self
def __next__(self):
if self.count < self.num:
self.a, self.b = self.b, self.a + self.b
self.count += 1
return self.a
raise StopIteration("")
测试
实例化
查看下实例化后的类型:
fib_num = FibNums(5)
# 查看类型
print(fib_num) # <__main__.FibNums object at 0x000000000298BF60>
print(type(fib_num)) # <class '__main__.FibNums'>
取值
方法一:通过next()取值
# 方法一:通过next()取值
print(next(fib_num)) # 1
print(next(fib_num)) # 1
print(next(fib_num)) # 2
打印结果
<__main__.FibNums object at 0x000000000298BF60>
<class '__main__.FibNums'>
1
1
2
方法二:for in
for i in fib_num:
print(i)
打印结果
1
1
2
3
5
生成器
生成器
- 就是迭代器语法简化的升级版
- 标志:yield
普通方法实现斐波那契
# 普通函数
def fib(num):
a, b = 0, 1
for _ in range(num):
a, b = b, a + b
return a
验证
res_19 = fib(19)
res_20 = fib(20)
print(res_19)
print(res_20)
结果
4181
6765
生成器实现
def fib2(num):
a, b = 0, 1
for _ in range(num):
a, b = b, a + b
yield a
验证
调用函数不是简单的获得返回值,而是创建生成器对象
res2_19 = fib2(19)
print(type(res2_19))
print(res2_19)
结果
<class 'generator'>
<generator object fib2 at 0x0000000009F5E6D8>
取值
方法一:
print(next(res2_19)) # 1
print(next(res2_19)) # 1
print(next(res2_19)) # 2
方法二:
for i in res2_19:
print(i)
结果
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
生成器创建
常见的有两种方法创建:
# 方法一:yield关键字的函数;
# 方法二:生成器表达式;
方法一:yield关键字的函数
def gen_a():
for i in range(1, 100, 2):
yield i
查看类型
print(gen_a()) # <generator object gen_a at 0x0000000009F5F9A8>
print(type(gen_a())) # <class 'generator'>
这种方式有一个简化版本
# 简化版本:
def gen_a2():
yield from range(1, 100, 2)
这里不做结果验证,从代码形式上看优于第一种方式,根据自己的需要,选择~~~
方法二:生成器表达式
表示方法:使用();
gen_b = (num for num in range(1, 100, 2))
print(gen_b) # <generator object <genexpr> at 0x0000000009F5F9A8>
print(type(gen_b)) # <class 'generator'>
取值
和之前一样,再啰嗦两句:
方法一:
print(next(gen_b))
print(next(gen_b))
print(next(gen_b))
方法二
for i in gen_b:
print(i)
补充
可迭代对象
列表,集合,字符串不叫迭代器,叫可迭代对象
l_test = [1, 2, 3, 4, 5, 6]
# print(next(l_test)) # TypeError: 'list' object is not an iterator
# 由上可以看出,列表不是迭代器,可以通过内置函数iter()将可迭代对象转换成iterator
l_iterator = iter(l_test)
print(type(l_iterator))
print(next(l_iterator))
print(next(l_iterator))
for i in l_iterator:
print(i)
打印结果
<class 'list_iterator'>
1
2
3
4
5
6
生成式
又称:推导式,解析式;
常见的有列表,字典,集合,生成器4类,都有其对应的生成式;
注意
元祖没有生成式、推导式
优势
- 代码格式简短且漂亮;
- 在数据量大的时候性能优于传统方式;
# 列表生成式(使用:[])
[num for num in range(1,100,2)]
# 集合生成式(注意:集合是一个无序不重复元素集;使用:{})
{num for num in range(1,100,2)}
# 字典推导式(同时取出键和值,中间用冒号分开;使用:{})
{num:num**2 for num in range(1,100,2)}
# 元祖没有生成式、推导式