effective python学习笔记_推导与生成

用推导取代map和filter

序列推导可取代map和filter,优越性有:1可读性强2不需要map的函数

控制推导逻辑的子表达式不要超过2个

推导的for层数最多建议两层,多了可读性会下降,反而用for循环会清晰

一层for内可连接多个if,if的关系为and:[i for i in range(20) if i % 2 ==0 if i % 3 == 0]

用赋值表达式消除推导中重复代码

序列推导中能定义变量的地方只有for内部,如果希望用if判断的结果,需要重写一遍if的内容,如果if用函数判断,那这个函数则要执行2次,用之前的知识可以通过海象运算符解决,可将函数调用次数只调一次

序列推导中海象运算符需要在for或if中先定义,如果在推导式中产生新值的地方(for前面)定义,然后在if引用,会报错变量未定义

如果在序列推导中没有if,然后在新值部分用了赋值表达式,那赋值表达式的变量会泄漏(类似于for i in range(5)),执行完后i是4,称这种叫泄漏。所以建议赋值表达式在序列推导中最好定义在if中

总结 1序列推导使用赋值运算符可简化代码提高可读性 2赋值运算符在序列推导里的定位位置建议优先在if中定义

函数不应该直接返回列表而是逐个生成列表里的值

当函数返回结果个数较多时,需要在函数构造返回列表并对列表append,消耗了一定代码,而且append是业务无关代码,体现不出业务,此时可用生成器,即yield,可避免结果列表的构造和append调用还能节省代码行还能节省构造列表产生的内存开销和列表操作时间开销

用yield注意点就是只能调用一次,再次调用需要重新调用函数,而不是把调用结果存到一个变量,下次调这个变量

小心迭代函数收到的参数

背景:当函数传入参数是生成器时,但函数内部又对这个生成器多次遍历,则只有第一次遍历会成功,其余遍历没有内容,可能会产生bug。但这样写的本意是减少对列表的构造,直接用序列

解决方法:在函数内部开始将生成器list化,但这样就起不到用生成器的优点了

解决方法1:改变函数的入参,不传入现成的生成器,而是传入产生生成器的函数,这样每次需要生成器时调用这个生成器函数,比如可以传入一个lambda匿名函数或者已经定义好的函数。这个方案的缺点是入参函数可读性可能较差,尤其是用lambda传入时

解决方法2:自定义一个实现__iter__方法的容器类,然后传参这个容器类的实例而不是解决方案1的入参函数。这样函数内每次遍历容器类时会调__iter__,每次调都会产生一个新的生成器。这个方案的缺点是每次构造生成器需要重新组装数据存在开销

综合解决方案:1先对入参校验类型,如果是自定义容器类可继续,如果是生成器则异常,判断生成器可用iter(generator) == generator实现,如果是生成器,iter(generator)会返回generator本身,让这个判别式为True,判断生成器类型也可使用collections.abc.Iterator类,然后用isinstance判断

用生成器表达式改写数据量较大的序列

数据量大时如果用列表生成则容易耗尽内存,此时建议用生成器,比较省内存

生成器也可以嵌套使用,即这个生成器定义时的数据来源可以是其他生成器

注意点是生成器只能用一次,多次使用时可以重新定义或调用其产生函数

用yield from连接多个生成器

连续使用多个生成器时,可能代码比较多

可以使用yield from优化,yield from后直接跟生成器,免去了for访问生成器,也节省代码行

不要用send给生成器注入数据

先快速理解send怎么玩

怎么理解:可理解为一个原子操作为先send再yield,而第一个yield前面需要有一个赋值,需要一个send,所以send None(因为send非None报错不知道为啥),后面正常操作即可

作用 生成器的send方法可实现对生成器双通道操作,即yield是生成器向外部传东西,而send是从外部向生成器内部传东西。使用yield很简单,对生成器迭代赋值即可,在生成器内部使用外部send进来的变量句法类似于a = yield b,最后a的值是外部send的传参而不是b,b是yield到外部的值

上面例子局限性 1看代码很难看懂,只有理解yield的人才能看懂 2多次调用时,总需要处理第一次send值为None的情况

解决方法 不用send了,send预期的结果可以通过向函数传递send参数列表组成的生成器实现,即避免了句法难懂和首次None的处理,功能也能ok

不要通过throw变换生成器的状态

原理 对生成器迭代时,可调用生成器的throw方法抛异常,此时如果成功抛异常,生成器下次next直接stopiteration,如果生成器处理了异常没有抛出,则next可继续往后迭代

好处 双通道

坏处 难懂,且要为生成器捕获异常写代码行,需要一些if else嵌套结构作为代码行开销

解决方法 不要通过throw给生成器注入,通过支持迭代(__iter__)的容器类作为解决方法,参数和异常通过类属性和类方法实现

考虑用itertools连接迭代器和生成器

迭代器连接方法

itertools.chain 首尾连接迭代器和生成器

itertools.repeat 构造元素重复指定次数的迭代器

itertools.cycle 迭代时循环返回入参的参数

itertools.tee 创多个平行迭代器

itertools.zip_longest zip压缩的多个迭代器长度不相同时,迭代次数为最长的那个迭代器,缺失值可提供参数fillvalue='xxx'实现

过滤迭代器元素

itertools.isslice(sequence, start_index, end_index, stride) 类似于序列切片

itertools.takewhile(sequence, take_condition)

itertools.dropwhile(sequence, drop_condition)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/681088.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Segmentation fault (core dumped)排查

先泼盆冷水,这个问题比较棘手,有的能通过重装opencv相关包修复,有的可能还是直接换一个没问题的环境比较快…… 我最后是没有解决的,折腾了几个小时后,还是听同事的话,把docker镜像重启了,幸好…

数据存储-SQLite

一般使用到数据库存储,涉及到的数据量都较大,采用文件存储也能完成,但是文件操作复杂,效率低,大量结构化数据通常采用关系型数据库存储较为合适。Android中已经嵌入了轻量级的关系型数据库SQLite,直接按照数…

PY计算生态是什么?

Python 的计算生态指的是与 Python 相关的广泛的软件、库、框架和工具集合. 它们为各种计算任务提供了丰富的解决方案和支持。Python 作为一种简洁、易学、功能强大的编程语言,在科学计算、数据分析、人工智能、机器学习等领域都有着强大的影响力。以下是 Python 计…

利用组合数进行幂集索引

在计算机科学中,通常使用二进制表示来表示子集的包含情况。如果集合中有n个元素,那么幂集的大小为2^n。考虑一个集合{a, b, c},其幂集为{{}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}。每个子集都可以用二进制数来表示&#xff0c…

每日两题 / 104. 二叉树的最大深度 102. 二叉树的层序遍历(LeetCode热题100)

104. 二叉树的最大深度 - 力扣(LeetCode) 递归判断,当前节点的最大深度为1 max(左节点的最大深度,右节点的最大深度) /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

回答篇:测试开发高频面试题目

引用之前文章:《测试开发高频面试题目》 https://blog.csdn.net/qq_41214208/article/details/138193469?spm1001.2014.3001.5502 本篇文章是回答篇(持续更新中) 1. 什么是测试开发以及其在软件开发流程中的作用。 a. 测试开发是指测试人员或…

Web LLM 攻击实验:利用 LLM API 实现 SQL 注入

前言 Web LLM 攻击 各组织都在急于集成大型语言模型 (LLM),以改善其在线客户体验。这使他们面临 Web LLM 攻击,这些攻击利用模型对攻击者无法直接访问的数据、API 或用户信息的访问权限。例如,攻击可能: 检索 LLM 有权访问的数…

Android 查看CUP占用率

查看每个进程CUP占用率的几种方式,由于自己充电界面老是导致整机温度过高,后面发现自己的线程一直在跑,相当于死循环,后面加上sleep才得以改善;先看看几种查询方式吧。 1、adb shell top 2、adb shell busybox top 3、adb shell …

美易官方:收盘美股涨跌不一,道指连续第6日收高

收盘之际,美股市场呈现出涨跌不一的态势,道指连续第6日收高,这无疑为投资者带来了一定的市场信心。然而,这种信心似乎并不稳固,因为市场的波动性和不确定性仍然存在。 美股周三收盘涨跌不一,道指连续第6个交…

Oracle数据库如何插入平方(²)立方(³)字符

第一步:创建数据表,字段一定要是NVARCHAR2类型的 第二步,插入数据用 unistr(1\00b3) 形式的写法 00b3 代表m,00b2代表㎡ SELECT * FROM TESTABC; UPDATE TESTABC set NAME1unistr(1\00b3); UPDATE TESTABC set NAME2unistr(2\00b2…

Mysql 8.0.33 迁移至 Postgresql 16.2

小伙伴们,你们好,我是老寇,我又回来,几个月不见,甚是想念啊!!!! 这不,云平台需要改造,将Mysql替换成Postgresql,话说回来&#xff0c…

日本站群服务器备受推崇:稳定性、性能、安全性超卓!

日本站群服务器备受推崇:稳定性、性能、安全性超卓! 在创建和运营网站的过程中,选择适合的服务器托管服务至关重要。日本站群服务器以其出色的稳定性、性能和安全性备受推崇。这篇文章将介绍日本站群服务器的优势,以及为何许多网站所有者和开…