python的一些高级特性记录小结,主要就是列表生成是和生成器的使用姿势

1. 列表生成式

如何快速的生成一个1,20的列表?

1
2
>>> list(range(1,20))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

如何生成 [1*1,2*2,...] 格式的列表?

1
2
>>> [ x*x for x in range(1,10)]
[1, 4, 9, 16, 25, 36, 49, 64, 81]

针对上面的列表再做一个小的限制,排除掉5*5这个,如何处理?

1
2
>>> list(x * x for x in range(1,10) if x!=5)
[1, 4, 9, 16, 36, 49, 64, 81]

简单来看下这个列表生成式规则,其实和jdk8中的lambda比较类似

1
元素的操作  for x in 列表 条件过滤

进阶版

多个列表式合在一起,组成多维数组遍历的效果

1
2
>>> list(x * y for x in range(1, 5) for y in range(2, 6))
[2, 3, 4, 5, 4, 6, 8, 10, 6, 9, 12, 15, 8, 12, 16, 20]

上面的结果等同于

1
2
3
4
5
6
7
>>> ans=[]
>>> for x in range(1, 5):
... for y in range(2, 6):
... ans.append(x*y)
...
>>> ans
[2, 3, 4, 5, 4, 6, 8, 10, 6, 9, 12, 15, 8, 12, 16, 20]

字典的遍历方式

1
2
3
4
>>> d
{'b': 23, 'cd': 12, 'd': 'add'}
>>> [k +"=" + str(v) for k,v in d.items()]
['b=23', 'cd=12', 'd=add']

2. 生成器

这是个比较有意思的东西,之前没有接触过,相比较于函数而言,主要特点如下

  • 函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
  • 而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

基本定义

形如生成式的使用方式,将中括号改成圆括号即可

1
2
3
4
5
6
7
8
9
>>> f=(x*x for x in range(1, 3))
>>> next(f)
1
>>> next(f)
4
>>> next(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

yield定义方式

对于无法写成列表生成式的,可以通过yield来实现,如著名的斐波拉契数列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 定义斐波拉契数列生成的函数,注意下面的yield语句
>>> def fib(x):
... a,b,n=0,1,0
... while n < x:
... yield b
... a,b=b,a+b
... n+=1
... return 'done'
...

## 开始使用,直接用for循环迭代使用
>>> for v in fib(10):
... print(v, end=' ')
...
1 1 2 3 5 8 13 21 34 55

使用姿势

使用生成器,常见的除了for循环使用之外,另一个就是如迭代器的使用姿势next(f);上面已经分别给出了使用的demo,注意下区别

  • 针对next使用时,最后一个时,会抛出一个异常StopIteration
  • 针对for循环使用时,无法获取函数的最终return结果

针对需要返回结果的case,下面给出while循环结合next的使用姿势进行演示如何处理

1
2
3
4
5
6
7
8
9
10
>>> f=fib(6)
>>> while(True):
... try:
... x = next(f)
... print(x, end=' ')
... except StopIteration as e:
... print('gen return', e.value)
... break
...
1 1 2 3 5 8 gen return done

小结

对于生成器而言,特别是yield方式,可以简单理解为每次在执行到yield的时候,直接退出函数的继续执行,并返回当前的结果;

当继续调用next时,从yield后面的代码继续执行,函数内所有的变量值都是上次的内容

II. 其他

1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

一灰灰blog

QrCode

知识星球

goals