【五一创作】python 基础系列篇:八、熟练掌握推导式

news2024/12/30 2:45:54

python 基础系列篇:八、熟练掌握推导式

  • 推导式
    • 特殊的元组推导式
  • 推导式机制
  • 玩转推导式
  • 小结

推导式

在python提供的各种语法糖中,老顾最青睐的就是这个推导式,他大大减少了代码的书写量。

比如一个正常的,生成长度为5的列表,其内容为连续自然数1到5,用正常的循环方式,书写就很长。

arr = []
for i in range(5):
    arr.append(i + 1)

而使用推导式,则就很简短

arr = [i + 1 for i in range(5)]

在 python 中,可以用推导式方式生成很多内容,比如 字典、列表、集合、元组。

# 列表推导式
[n for n in range(100)]
# 集合推导式
{n for n in range(100)}
# 字典推导式
{n:n for n in range(100)}
# 元组推导式
(n for n in range(100))

CSDN 文盲老顾的博客,https://blog.csdn.net/superwfei

特殊的元组推导式

在其他推导式方式中,每次都是得到对应类型的数据,即:推导即结果。

而在元组推导式方式中,比较特殊,他得到的并不是一个元组结果,而是一个生成式类型的结果。

在这里插入图片描述
只有在第一次使用的时候,他才会转成元组数据,但是,这个推导式是不可复用的,需要自行注意。

推导式机制

1、只能使用迭代

在推导式中,我们只能使用迭代方式进行推导,也就是说,只能使用 for。因为迭代对象是有限的,所以,得到的长度在推导式运行之前就已经确定了,内容也确定了,只是省略了我们的复制步骤。

2、不能引用自身数据

同样,我们无法在推导式内引用之前步骤生成的数据,比如我们想直接用推导式生成一个斐波那契数列,那是不可以的(使用公式进行计算的除外)。

3、可以使用三元表达式

[n + 1 if n % 2 == 1 else n // 2 for n in range(10)]
Out[6]: [0, 2, 1, 4, 2, 6, 3, 8, 4, 10]

[n + 1 if n % 2 == 1 else n // 2 + 1 for n in range(10)]
Out[7]: [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]

在这里插入图片描述
在 for 之前的 if else 即为三元运算。这个方式是无论条件是否满足,都会有数据生成在推导式结果内。

本例推导式等价于

def tempFun():
	arr = []
	for n in range(10):
		if n % 2 == 1:
			arr.append(n + 1)
		else:
			arr.append(n // 2 + 1)
	return arr

4、筛选表达式

[n for n in range(40) if n % 3 == 0 and n > 0]
Out[8]: [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39]

在这里插入图片描述
在迭代表达式之后的 if ,即为筛选表达式,只有满足条件的内容,才会生成在推导式结果内,如果不满足,则不会在推导式结果中体现。

本例推导式等价于

def tempFun():
	arr = []
	for n in range(40):
		if n % 3 == 0 and n > 0:
			arr.append(n)
	return arr

5、多重迭代推导式

这里所说的多重迭代推导式,是并列的多个 for 迭代,而不是嵌套迭代哦。

# 嵌套迭代推导式
[[n + m * 5 for n in range(5)] for m in range(5)]

在这里插入图片描述

# 多重迭代推导式
[n for n in range(5) for m in range(5)]

在这里插入图片描述
根据结果,我们可以得出一个结论,那就是:多重迭代推导式,顺序是从左向右的。

先迭代一次 n,得到 n=0,然后迭代5次m,结果生成5个0,然后再迭代一次n,得到n=1,然后迭代5次m,结果生成5个1。。。。直到最左边的迭代结束,我们可以用下边这个推导式再次验证一下。

[[x,y,z] for x in range(3) for y in range(3) for z in range(3)]
Out[11]: 
[[0, 0, 0],
 [0, 0, 1],
 [0, 0, 2],
 [0, 1, 0],
 [0, 1, 1],
 [0, 1, 2],
 [0, 2, 0],
 [0, 2, 1],
 [0, 2, 2],
 [1, 0, 0],
 [1, 0, 1],
 [1, 0, 2],
 [1, 1, 0],
 [1, 1, 1],
 [1, 1, 2],
 [1, 2, 0],
 [1, 2, 1],
 [1, 2, 2],
 [2, 0, 0],
 [2, 0, 1],
 [2, 0, 2],
 [2, 1, 0],
 [2, 1, 1],
 [2, 1, 2],
 [2, 2, 0],
 [2, 2, 1],
 [2, 2, 2]]

本例推导式等价于

def tempFun():
	arr = []
	for x in range(3):
		for y in range(3):
			for z in range(3):
				arr.append([x,y,z])
	return arr

6、多重迭代筛选推导式

[[x,y,z] for x in range(10) if x % 2 == 0 for y in range(10) if y % 3 == 0 for z in range(10) if z % 5 == 0]
Out[15]: 
[[0, 0, 0],
 [0, 0, 5],
 [0, 3, 0],
 [0, 3, 5],
 [0, 6, 0],
 [0, 6, 5],
 [0, 9, 0],
 [0, 9, 5],
 [2, 0, 0],
 [2, 0, 5],
 [2, 3, 0],
 [2, 3, 5],
 [2, 6, 0],
 [2, 6, 5],
 [2, 9, 0],
 [2, 9, 5],
 [4, 0, 0],
 [4, 0, 5],
 [4, 3, 0],
 [4, 3, 5],
 [4, 6, 0],
 [4, 6, 5],
 [4, 9, 0],
 [4, 9, 5],
 [6, 0, 0],
 [6, 0, 5],
 [6, 3, 0],
 [6, 3, 5],
 [6, 6, 0],
 [6, 6, 5],
 [6, 9, 0],
 [6, 9, 5],
 [8, 0, 0],
 [8, 0, 5],
 [8, 3, 0],
 [8, 3, 5],
 [8, 6, 0],
 [8, 6, 5],
 [8, 9, 0],
 [8, 9, 5]]

在每一个迭代后边,都可以跟上一个筛选表达式,这是合法的。

本例推导式等价于

def tempFun():
	arr = []
	for x in range(10):
		if x % 2 == 0:
			for y in range(10):
				if y % 3 == 0:
					for z in range(10):
						if z % 5 == 0:
							arr.append([x,y,z])
	return arr

玩转推导式

推导式本身,并不限定嵌套的推导式层数,根据这个,我们可以试着写一个素数判断,比如来个1000以内的所有素数。

[n for n in range(2,1000) if len([x for x in range(2,n) if n % x == 0]) == 0]

在比如,要求每行5个输出素数

print(''.join([v + ' ' if i % 5 != 4 else v + '\n' for i,v in enumerate([str(n) for n in range(2,1000) if len([x for x in range(2,n) if n % x == 0]) == 0])]))

更比如,输出所有三位数的素数,且这个素数的每一位也都是素数

print(''.join([v + ' ' if i % 5 != 4 else v + '\n' for i,v in enumerate([str(n) for n in range(100,1000) if len([x for x in range(2,n) if n % x == 0]) == 0 and len(set(str(n)) - set('2357')) == 0])]))

比如统计一段文本中,每个字符出现的次数

a = 'aw;oei ja;ofnme; aoiwejf;aoiewj;lz uj;orijdfsoerijhg;osef'
print({c:a.count(c) for c in set(a)})
{'l': 1, 'e': 6, 'h': 1, 'n': 1, 'd': 1, ';': 7, 'w': 3, 'o': 7, 's': 2, 'z': 1, 'j': 6, ' ': 3, 'a': 4, 'r': 2, 'f': 4, 'g': 1, 'm': 1, 'u': 1, 'i': 5}

再比如,降序输出每个字符出现的次数

a = 'aw;oei ja;ofnme; aoiwejf;aoiewj;lz uj;orijdfsoerijhg;osef'
print({c:a.count(c) for c in sorted({c for c in set(a)},key = lambda x:(-a.count(x),x))})
{';': 7, 'o': 7, 'e': 6, 'j': 6, 'i': 5, 'a': 4, 'f': 4, ' ': 3, 'w': 3, 'r': 2, 's': 2, 'd': 1, 'g': 1, 'h': 1, 'l': 1, 'm': 1, 'n': 1, 'u': 1, 'z': 1}

小结

经过本文的一些示例,相信小伙伴们也对这个推导式有了进一步的认知了。由于推导式的嵌套方式比较方便,比我们单独写循环要便捷很多很多,所以在一些确定计算方式的内容,老顾都会用推导式来进行数据整理,有兴趣的可以到老顾的社区,看看每日一练的做法,大部分都是由推导式进行完成的。

对于推导式来说,关键是可迭代的对象作为初始数据来源,range 是最常用的,其次是 enumerate,再然后就是各个已存在的列表、字典、元组、集合或其他可迭代对象,比如正则迭代之类的。

在这里再向大家推荐一个迭代工具包,itertools,非常好用哦,它内置了一些方法,方便的生成一些可迭代对象。

总之呢,学会用好退到时候,是懒人的一大福音哦。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

红黑树的概念与实现

目录 ​一、红黑树的概念 1.什么是红黑树 2.红黑树满足的性质 3.红黑树存在的意义 二、红黑树的实现 1.类的构建 2.插入函数 (1)插入一个节点 (2)调整节点 (3)旋转 三、红黑树的检验 一、红黑树…

okio篇2-RealBufferedSource

上一篇讲过,okio只有两个概念,source和sink。source对应InputStream,即负责将数据读出,是一个输出方(所以只有source.read方法)。sink对应outputStream,负责获取数据写入,是一个写入…

RT-Thread Nano在keil Simulator中的仿真

目的:使用STM32CubeMX生成包含RT-Thread Nano内核和FinSH控制台的keil工程,在没有硬件开发板的情况下,通过keil Simulator来运行系统,并通过SHELL来与系统进行交互。 一、使用STM32CubeMX生成RT-Thread Nano工程 官方文档已经说…

C++标准库 -- 动态内存 (Primer C++ 第五版 · 阅读笔记)

C标准库 --动态内存 (Primer C 第五版 阅读笔记) 第12章 动态内存------(持续更新)12.1、动态内存与智能指针12.1.1、shared_ptr类12.1.2、直接管理内存12.1.3、shared_ptr和new结合使用12.1.4、智能指针和异常12.1.5、unique_ptr12.1.6、weak_ptr 12.2、动态数组1…

网络通信之网络层与数据链路层

文章目录 讲在前面网络层网络层概述IP协议格式网段划分公有IP、私有IP、特殊IP理解路由 数据链路层MAC地址以及MAC帧(以太网帧)MTU协议MTU对IP和TCP协议的影响ARP协议及其作用 涉及到的相关协议DNS协议(应用层)NAT与NAPT协议 总结…

BEV (0)---DETR

1 DETR 1.1 DETR处理流程 1.1.1 将图像输入给Backbone获得图像特征与位置编码 ①. 对给定的输入图像通过resnet进行特征提取,最终得到特征图C5∈RBx2048xhxw,其中h、w为输入图像尺寸得1/32。随后再用一层11卷积压缩一下通道,得到特征图P5∈RBx256xhxw。…

jvm调优策略

jvm调优主要是内存管理方面的调优,包括各个代的大小,GC策略等。 代大小调优 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物…

数据结构学习记录——什么是堆(优先队列、堆的概念、最大堆最小堆、优先队列的完全二叉树表示、堆的特性、堆的抽象数据类型描述)

目录 优先队列 若采用数组或链表实现优先队列 数组 链表 有序数组 有序链表 总结 若采用二叉搜索树来实现优先队列 最大堆 堆的概念 优先队列的完全二叉树表示 堆的两个特性 结构性 有序性 【例】最大堆和最小堆 【例】不是堆 堆的抽象数据类型描述 优先队列…

安排超市 -- BFS分割搜索

4.安排超市 给定一个n*n的地图。地图是上下左右四联通的,不能斜向行走: *代表障碍,不可通行。 .代表路,可以通行。 #代表房子。房子也是可以通行的。 小红现在需要在一些地方安排一些超市(不能安排在障碍物上&#xf…

山东专升本计算机第七章-计算机网络基础

计算机网络基础 计算机网络系统 考点 6 计算机网络硬件 主体设备 • 称为主机 • 一般可分为中心站(又称服务器)和工作站(客户机) 连接设备 • 网卡 • 工作在数据链路层 • 网卡又称网络适配器,是连接主机和网…

【C++初阶】引用

一.概念 引用就是取别名,在语法上它不会开空间,而是和它引用的变量共用同一块空间。对引用的操作也就是对原来变量的操作。就像现实生活中给人取外号一样,不管是喊外号还是本名,指的都是那个人。 二.引用特性 1.引用类型必须和引用…

Java8 新特性讲解

一、Lambda表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。 二、函数式接口 &#…

【网课平台】Day15.Devops:持续集成与持续交付

文章目录 一、Devops1、什么是Devops2、什么是CI/CD3、Devops方案参考 二、人工部署1、项目打jar包2、生成镜像、创建容器 三、自动化部署1、代码提交到git2、修改pom.xml文件3、前端部署 一、Devops 1、什么是Devops 一个软件的生命周期包括:需求分析阶、设计、开…

SpringCloud:ElasticSearch之集群

单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点单点故障问题:将分片数据在不同节…

【原创】运维的终点是开发~chatGPT告诉你真相

文章目录 软件技术岗位鄙视链,你在哪层呢?让chatGPT告诉你运维工作好,还是开发工作好问它几个问题1. 一个三年运维成长的案例和薪资2. 一个三年开发成长的案例和薪资3. 一个五年运维成长的案例和薪资4. 一个五年开发成长的案例和薪资5. 一个十…

云分析迁移:顺应需求

云提供了对新分析功能、工具和生态系统的访问,可以快速利用这些功能、工具和生态系统来测试、试点和推出新产品。然而,尽管迫在眉睫,但企业在将分析迁移到云时仍感到担忧。组织正在寻找能够帮助他们分配资源和集成业务流程的服务提供商&#…

Linux 服务器上安装和使用 Redis,只需这 4 步!

一、使用 yum 安装 Redis 使用以下命令,直接将 redis 安装到 linux 服务器: yum -y install redis 二、配置远程连接 a)首先第一步,将 redis 配置文件下载到本地(如果你熟悉 vim 操作,直接用 vim 编辑即可…

论文阅读《PIDNet: A Real-time Semantic Segmentation Network Inspired by PID》

论文地址:https://arxiv.org/pdf/2206.02066.pdf 源码地址:https://github.com/XuJiacong/PIDNet 概述 针对双分支模型在语义分割任务上直接融合高分辨率的细节信息与低频的上下文信息过程中细节特征会被上下文信息掩盖的问题,提出了一种新的…

【五一创作】Springboot+多环境+多数据源(MySQL+Phoenix)配置及查询(多知识点)

文章目录 1. 背景2. 技术点3 子模块依赖SpringBoot设置4. 多环境配置4.1 application.yml4.2 application-pro.yml 5. 多数据源配置5.1 yml配置5.2 自定义数据源在Java中配置5.2.1 PhoenixDataSourceConfig5.2.2 MysqlDataSourceConfig 6. 完整的Pom6. 测试6.1 Mapper配置6.2 方…

字符、块、网络设备

设备模型(的意义) 降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发&#…