热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。
本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。


全系列
(一)python基础
(二)函数
(三)高级特性
(四)函数式编程
(五)面向对象编程


高级特性


迭代

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

>>> for ch in 'ABC':
... print(ch)
...
A
B
C

如何判断一个对象是可迭代对象呢?方法是通过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 "", 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>#如果要一个一个打印出来&#xff0c;可以通过next()函数获得generator的下一个返回值&#xff1a;>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
...
# 计算到最后一个元素&#xff0c;再next会报错
>>> next(g)
Traceback (most recent call last):File "", line 1, in <module>
StopIteration# 正确的方法是for循环
>>> g &#61; (x * x for x in range(10))
>>> for n in g:
... print(n)

  • 函数实现

def fib(max):n, a, b &#61; 0, 0, 1while n < max:print(b)a, b &#61; b, a &#43; bn &#61; n &#43; 1return &#39;done&#39;

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

def fib(max):n, a, b &#61; 0, 0, 1while n < max:yield ba, b &#61; b, a &#43; bn &#61; n &#43; 1return &#39;done&#39;

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

def odd():print(&#39;step 1&#39;)yield 1print(&#39;step 2&#39;)yield(3)print(&#39;step 3&#39;)yield(5)>>> o &#61; odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):File "", line 1, in <module>
StopIteration

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

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

迭代器

可以直接作用于for循环的对象统称为可迭代对象&#xff1a;Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象。

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

可以被next()函数调用并不断返回下一个值的对象称为迭代器&#xff1a;Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象。

总结&#xff1a;


  • 凡是可作用于for循环的对象都是Iterable类型&#xff1b;
  • 凡是可作用于next()函数的对象都是Iterator类型&#xff0c;它们表示一个惰性计算的序列&#xff1b;
  • 集合数据类型如list、dict、str等是Iterable但不是Iterator&#xff0c;不过可以通过iter()函数获得一个Iterator对象。
    更多关于迭代对象和迭代器的知识见&#xff1a;https://www.jianshu.com/p/d917b37030ef
    https://www.jb51.net/article/190712.htm



补充


可迭代对象和迭代器的本质&#xff1a;

在这里插入图片描述


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

for…in…循环本质

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


生成器和yield


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

参考链接&#xff1a;

Python 的关键字 yield 有哪些用法和用途&#xff1f;
python中yield的用法详解——最简单&#xff0c;最清晰的解释


推荐阅读
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
author-avatar
Lovepetall
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有