200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > python学习--关注容易被忽略的知识点--(三)高级特性

python学习--关注容易被忽略的知识点--(三)高级特性

时间:2019-12-24 02:02:54

相关推荐

python学习--关注容易被忽略的知识点--(三)高级特性

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。

本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。

全系列

(一)python基础

(二)函数

(三)高级特性

(四)函数式编程

(五)面向对象编程

高级特性

迭代

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。如:

>>> for ch in 'ABC':...print(ch)...ABC

如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

>>> from collections import Iterable>>> isinstance('abc', Iterable) # str是否可迭代True>>> isinstance([1,2,3], Iterable) # list是否可迭代True>>> isinstance(123, Iterable) # 整数是否可迭代False

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

>>> [x * x for x in range(1, 11)][1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 双层循环>>> [m + n for m in 'ABC' for n in 'XYZ']['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

列表生成式+if…else

不能在for循环后面加else,在for循环前面加if必须加上else

>>> [x if x % 2 == 0 for x in range(1, 11)]File "<stdin>", line 1[x if x % 2 == 0 for x in range(1, 11)]^SyntaxError: invalid syntax>>> [x if x % 2 == 0 else -x for x in range(1, 11)][-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

在一个列表生成式中,for前面的if … else是表达式,而for后面的if是过滤条件,不能带else。

生成器

列表生成式的缺点是会受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,会占用很大的存储空间,存储效率大大降低。

在Python中,生成器(generator)是一种一边循环一边计算的机制,可以在循环的过程中不断推算出后续的元素,因此不必创建完整的list,从而节省大量空间。

创建生成器的方法

将列表生成式的[]改为()

>>> L = [x * x for x in range(10)]>>> L[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x * x for x in range(10))>>> g<generator object <genexpr> at 0x1022ef630>#如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:>>> next(g)0>>> next(g)1>>> next(g)4>>> next(g)...# 计算到最后一个元素,再next会报错>>> next(g)Traceback (most recent call last):File "<stdin>", line 1, in <module>StopIteration# 正确的方法是for循环>>> g = (x * x for x in range(10))>>> for n in g:...print(n)

函数实现

def fib(max):n, a, b = 0, 0, 1while n < max:print(b)a, b = b, a + bn = n + 1return 'done'

上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:

def fib(max):n, a, b = 0, 0, 1while n < max:yield ba, b = b, a + bn = n + 1return 'done'

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

def odd():print('step 1')yield 1print('step 2')yield(3)print('step 3')yield(5)>>> o = odd()>>> next(o)step 11>>> next(o)step 23>>> next(o)step 35>>> next(o)Traceback (most recent call last):File "<stdin>", line 1, in <module>StopIteration

用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

>>> g = fib(6)>>> while True:...try:... x = next(g)... print('g:', x)...except StopIteration as e:... print('Generator return value:', e.value)... break...g: 1g: 1g: 2g: 3g: 5g: 8Generator return value: done

迭代器

可以直接作用于for循环的对象统称为可迭代对象:Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象。

>>> from collections.abc import Iterable>>> isinstance([], Iterable)True>>> isinstance({}, Iterable)True>>> isinstance('abc', Iterable)True>>> isinstance((x for x in range(10)), Iterable)True>>> isinstance(100, Iterable)False

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用isinstance()判断一个对象是否是Iterator对象。

总结:

凡是可作用于for循环的对象都是Iterable类型;凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

更多关于迭代对象和迭代器的知识见:/p/d917b37030ef

/article/190712.htm

补充

可迭代对象和迭代器的本质:

可迭代对象通过__iter__方法向我们提供一个迭代器,我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据.一个具备了__iter__方法的对象,就是一个可迭代对象。list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。iter()函数实际上就是调用了可迭代对象的__iter__方法。迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。一个实现了__iter__方法和next()方法的对象,就是迭代器。除了Python内置的iter之外,还可以通过Python内置的工具包itertools创建迭代器。

for…in…循环本质

for item in Iterable循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。

生成器和yield

生成器一定是迭代器,但是迭代器不全是生成器对象。生成器的的特点是运行速度块,最大优点是节省内存。包含yield关键字的函数将是一个生成器对象。这个生成器有一个函数就是next函数,next就相当于“下一步”生成哪个数,这一次的next开始的地方是接着上一次的next停止的地方执行的,所以调用next的时候,生成器并不会从foo函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。除了yield之外,在Python3.3之后还加入了yield from获取生成器,允许一个生成器将其部分操作委派给另一个生成器,yield from后面需要加上可迭代对象,这样可以把可迭代对象变成生成器。python3的range()就是xrange(),便是一个生成器。yield的另外用法包括协程、定义上下文管理器。

参考链接:

Python 的关键字 yield 有哪些用法和用途?

python中yield的用法详解——最简单,最清晰的解释

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。