Python进阶之列表推导与生成器表达式详解
作者:生鱼同学 发布时间:2022-01-18 00:07:04
在python学习的过程中,我们最先接触到的就是python的数组,元组,字典等基础类型,但很少有人深入讨论python的内置序列类型以及它们的高级使用姿势。
深度学习python的内置序列,不仅能让我们编写的API更加的易用简介,也能够更好的理解python中各种序列的特性。
在本文中,我们就来一起解锁python内置序列的高级用法,玩转pyhon序列。
内置序列类型
python中有很多的序列类型,主要可以分为以下两类:
容器序列:能存放不同数据类型的数据的序列。(list, tuple, collections.deque)
扁平序列:只能容纳一种类型的序列。(str, bytes, bytearray, memoryview, array.array)
说明:扁平序列储存的是一段连续的内存空间,而容器序列存放的是它们包含的任意类型对象的引用。
另外,序列类型还可以从可修改与不可修改的角度进行分类,主要能被分成以下两类:
可变序列:list, bytearray, array.array, collections.deque, memoryview
不可变序列:str, tuple, bytes
为了深入的讨论可变序列与不可变序列的差异,我们看下面这个UML图:
在上图中,继承从子类指向超类,可以看到可变序列(MutableSequence)继承了不可变序列(Sequence)的很多方法。与此同时,通过UML图我们也可以更直观的发现其不同的地方,这有助于我们了解后续的内置序列类型的差异。
列表推导与生成器表达式
列表推导
相信大家已经对基础的序列类型list有了初步的了解与认识,但当我们想要创建一个新的数组时,往往会想到使用for循环遍历生成。
其实在python中还存在一种构建列表的方法叫做列表推导(list comprehension),它是构建列表的快捷方式,同时也能够使你的代码更加易读与简洁。假设我们需要创建从0到10的一个列表,我们来看下面的两段代码:
# 不使用列表推导
example_list_01 = []
for i in range(10):
example_list_01.append(i)
print(example_list_01)
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表推导
example_list_01 = [i for i in range(10)]
print(example_list_01)
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
相信大部分人第一时间都会考虑使用第一种方法进行列表的创建,但明显使用了列表推导(生成器表达式推导列表)的例子看起来更加简便且易读。我们再来看一个更复杂的例子,假设我们想要寻找10以内的偶数,我们看下面两段代码:
# 不使用列表推导
example_list_02 = []
for i in range(10):
if i % 2 == 0:
example_list_02.append(i)
print(example_list_02)
# 列表推导
example_list_02 = [i for i in range(10) if i % 2 == 0]
print(example_list_02)
显然,下面的代码可读性更强且更为简单。另外,使用filter也能够完成上述的功能,但是可读性并不强。我们使用filter完成上述功能的代码如下:
example_list_03 = list(filter(lambda i: i % 2 == 0, range(10)))
print(example_list_03)
显然,这样的可读性并不强。
在列表推导中,我们还可以将自己的函数或者python内置函数直接对生成的数组进行处理,请看下面这个例子:
def deal(num):
return '处理过的' + str(num)
deal_list = [deal(i) for i in range(10)]
print(deal_list )
>>> ['处理过的0',
'处理过的1',
'处理过的2',
'处理过的3',
'处理过的4',
'处理过的5',
'处理过的6',
'处理过的7',
'处理过的8',
'处理过的9']
最后,我们再用列表推导表达式尝试计算笛卡尔积并与for循环完成的相同的功能做对比,请看下面的代码:
colors = ['红色','蓝色','绿色']
clothes = ['上衣','裤子','运动鞋']
clothes_list_01 = []
for color in colors:
for clothe in clothes:
clothes_list_01.append((color,clothe))
print('未使用列表推导:',clothes_list_01)
clothes_list_02 = [(color,clothe) for color in colors for clothe in clothes]
print('使用列表推导:',clothes_list_01)
结果如下:
未使用列表推导: [('红色', '上衣'), ('红色', '裤子'), ('红色', '运动鞋'),
('蓝色', '上衣'), ('蓝色', '裤子'), ('蓝色', '运动鞋'), ('绿色', '上衣'), ('绿色', '裤子'), ('绿色', '运动鞋')]
使用列表推导: [('红色', '上衣'), ('红色', '裤子'), ('红色', '运动鞋'),
('蓝色', '上衣'), ('蓝色', '裤子'), ('蓝色', '运动鞋'), ('绿色', '上衣'), ('绿色', '裤子'), ('绿色', '运动鞋')]
可以看到输出的结果是完全相同的,但是利用列表推导的代码更为简洁。
生成器表达式
虽然使用上述的列表推导语法也可以生成元组等其他类型的序列,但是使用生成器表达式会更好。生成器并不是先建立一个完整的列表再将其传递到某个构造函数内,而是逐个产出元素,这会更加的节省内存。
我们看下面几个例子,用来了解生成器表达式是如何生成字典与元组的。
# 使用生成器表达式构建字典
dict_transform_list = [('APPLE', '苹果'), ('BNANA', '香蕉'), ('PEAR', '梨子')]
dict_01 = {key: value for key,value in dict_transform_list}
>>>{'APPLE': '苹果', 'BNANA': '香蕉', 'PEAR': '梨子'}
# 使用生成器表达式构建元组
tuple_01 = tuple(i for i in range(10))
>>>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
来源:https://juejin.cn/post/7221862036544454717


猜你喜欢
- Socket的基本背景在讨论这两个选项的区别时,我们需要知道的是BSD实现是所有socket实现的起源。基本上其他所有的系统某种程度上都参考
- 一、字符串(str)字符串转换为列表使用list()方法str_1 = "1235"str_2 = 'zhang
- 单线程+多任务异步协程协程在函数(特殊函数)定义的时候,使用async修饰,函数调用后,内部语句不会立即执行,而是会返回一个协程对象任务对象
- 环境Django 2.0 + Win 10 + Pycharm + 360浏览器报错项目结构(报异常)解决方法看了好多大佬的解决方法,基本上
- 在做项目中遇到这样一个问题,就是我们需要添加几组数据到数据库,但是具体几组数据不确定,有客户来填写,比如我们需要添加打折策略,可能个策略有很
- 背景最近处理文本文档时(文件约2GB大小),出现memoryError错误和文件读取太慢的问题,后来找到了两种比较快Large File R
- 我就废话不多说了,大家还是直接看代码吧!talk is cheap from openpyxl import Workbook
- 问题如何设定matplotlib输出的图片大小?import matplotlib.pyplot as plt一、plt.figure(fi
- 这篇文章主要介绍了python global和nonlocal用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学
- Mysql字段为null的加减乘除运算数据库表test_table如下查询:select id,total,used,(total - us
- 大家好,我叫斑马纹列表中使用两种相同的样式但颜色不同的背景,来间隔显示的内容。当然这个释义我是借鉴《designing interfaces
- 使用matplotlib中的一些函数将tensorflow中的数据可视化,更加便于分析import tensorflow as tfimpo
- python方法实现字符串反转方法一:反转列表法Python中,列表可以进行反转,我们只要把字符串转换成列表,使用reverse()方法,进
- 阅读作者上一篇文章:段正淳的css笔记(4)css代码的简写CSS未知图片垂直居中的方法:一天大家在团队中讨论“未知图片垂直居中”的问题,突
- 目录问题复现隐式转换总结参考问题在工作中发现,有一个接口只执行一条SQL查询语句,并且SQL明明使用了主键列,但是速度很慢。在MySQL中E
- 最近开始学习Python,但只限于看理论,编几行代码,觉得没有意思,就想能不能用Python编写可视化的界面。遂查找了相关资料,发现了PyQ
- 背景基于现在微服务或者服务化的思想,我们大部分的业务逻辑处理函数都是长这样的:比如grpc服务端:func (s *Service) Get
- 如果你取相对路径不是在主文件里,可能就会有相对路径问题:"No such file or directory"。因为 p
- asp函数实现把数字格式化为每3个数字时以逗号间隔的数字见下:<%Function Comma(str)If No
- 需求:该接口,含两个参数,一个是file,一个是paperName。其中file为上传的文件。content-type为form-data。