
4.7 推导式与生成器推导式
推导式(Comprehensions,又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。Python中共有三种推导式,在Python 2和Python 3中都有支持:列表(list)推导式、字典(dict)推导式、集合(set)推导式。推导式的最大优势是简化代码,主要适合于创建或控制有规律的序列。
4.7.1 列表推导式
使用列表推导式可以快速生成一个列表,或者根据某个列表生成满足指定需求的列表。列表推导式通常有以下几种常用的语法格式。
1.生成指定范围的数值列表
语法格式如下。

参数说明:
● listname:表示生成的列表名称。
● expression:表达式,用于计算新列表的元素。
● var:循环变量。
● range:采用range函数生成的range对象。
【例4-65】 要生成一个包括5个随机数的列表,要求数的范围在1~10(包括10)。

运行结果:

2.根据列表生成指定需求的列表
语法格式如下。

参数说明:
● newlist:表示新生成的列表名称。
● expression:表达式,用于计算新列表的元素。
● var:变量,值为后面列表的每个元素值。
● oldlist:用于生成新列表的原列表。
【例4-66】 有一组不同配置的计算机形成的价格列表,应用列表推导式生成一个打95折的价格列表。

运行结果:

3.从列表中选择符合条件的元素组成新的列表
语法格式如下。

此处if主要起条件判断作用,oldlist数据中只有满足if条件的才会被留下,最后统一生成为一个数据列表。
参数说明:
● newlist:表示新生成的列表名称。
● expression:表达式,用于计算新列表的元素。
● var:变量值为后面列表的每个元素值。
● oldlist:用于生成新列表的原列表。
● condition:条件表达式,用于指定筛选条件。
【例4-67】 有一组不同配置的计算机形成的价格列表,应用列表推导式生成一个高于5000元的价格列表。

运行结果:

4.多个for实现列表推导式
多个for的列表推导式可以实现for循环嵌套功能。
【例4-68】 多个for实现列表推导式应用:求(x,y),其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表。

运行结果:

4.7.2 字典推导式
字典推导式的语法格式如下。

这里和list有所不同,因为dict里面有两个关键的属性,key和value。字典推导式的作用是快速合并列表为字典或提取字典中的目标数据。
1.利用字典推导式创建一个字典
【例4-69】 生成字典key,包含1-5这5个数字,value是这个数字的2次方。

运行结果:

2.将两个列表合并为一个字典
【例4-70】 利用字典推导式将两个列表合并为一个字典的示例。

运行结果:

将两个列表合并为一个字典,要注意如下两点。
1)如果两个列表数据个数相同,len统计任何一个列表的长度都可以。
2)如果两个列表数据个数不同,len统计数据多的列表数据个数会报错;len统计数据少的列表数据个数不会报错。
3.提取字典中的目标数据
【例4-71】 提取计算机价格大于等于2000的字典数据。

运行结果:

4.7.3 集合推导式
集合推导式跟列表推导式是相似的,唯一的区别就是它使用的是大括号。
集合推导式的代码格式如下:

【例4-72】 将名字去重并把名字的格式统一为首字母大写。

运行结果:

4.7.4 元组的生成器推导式
元组一旦创建,没有任何方法可以修改元组中的元素,只能使用del命令删除整个元组。由于Python内部对元组做了大量优化,所以访问和处理速度比列表快。
生成器推导式的结果是一个生成器对象,而不是列表,也不是元组。使用生成器对象的元素时,可以根据需要将其转化为列表或元组。可以使用__next__()方法或者内置函数访问生成器对象,但不管使用何种方法访问其元素,当所有元素访问结束以后,如果需要重新访问其中的元素,则必须重新创建该生成器对象。
生成器对象的创建与列表推导式的创建不同的地方就是,生成器推导式是用圆括号创建。
使用元组推导式可以快速生成一个元组,它的表现形式和列表推导式类似,只是将列表推导式中的中括号“[]”修改为小括号“()”。
【例4-73】 使用元组推导式生成一个包含5个随机数的生成器对象。

print(”由随机数生成的元组对象:”,randnum)
运行结果:

从上面的执行结果中可以看出,使用元组推导式生成的结果并不是一个元组或者列表,而是一个生成器对象,这一点和列表推导式是不同的。要使用该生成器对象,可以将其转换为元组或者列表。其中,转换为元组使用tuple函数,而转换为列表则使用list函数。
【例4-74】 使用元组推导式生成一个包含5个随机数的生成器对象,然后将其转换为元组并输出。


运行结果:

要使用通过元组推导器生成的生成器对象,还可以直接通过for循环遍历或者直接使用方法进行遍历。
【例4-75】 通过生成器推导式生成一个包括5个元素的生成器对象number,然后应用for循环遍历该生成器对象,并输出每个元素的值,最后再将其转换为元组输出。

运行结果:
