![2d58d27204ba0f9b9794238dc316b5e4.png](https://i-blog.csdnimg.cn/blog_migrate/3612bffcc7fed195945ce573c6257f7f.jpeg)
作者:Zarten 知乎专栏:Python基础深入详解 知乎ID: Zarten 简介: 互联网一线工作者,尊重原创并欢迎评论留言指出不足之处,也希望多些关注和点赞是给作者最好的鼓励 !
概述
python中推导式用起来更加简洁方便,可读性也大大提升,完全可以替代filter()和map()函数。使用起来可以达到事半功倍的效果!
常见的推导式包括:列表推导式、字典推导式、集合推导式。下面将详细讲述。
其中包括一些注意点,下面都会有讲解,如:
1.变量的作用域问题
2.多层for循环的顺序问题
3.条件过滤的写法
4.太多层for循环的可读性问题
列表推导
提示:所有推导式中的一些共性将会在列表推导中讲述,所以后面的字典推导和集合推导的一些共有特性不会再单独讲述。
- 最简单的列表推导
names = ['zarten_1', 'zarten_2', 'zarten_3']
names_ex = [name.title() for name in names] #将首字母变为大写
print('names_ex:', names_ex)
![2b9566608f49dcd7aff119fc72006b2b.png](https://i-blog.csdnimg.cn/blog_migrate/ba4947104880c19cea4d9049d69240d1.png)
- 作用域问题
在推导式中的变量的作用域只在表达式内有效的,不用担心变量泄露的问题。
names = ['zarten_1', 'zarten_2', 'zarten_3']
name = 'zhihu_id:Zarten'
names_ex = [name.title() for name in names] #将首字母变为大写,且name只在此作用域内
print('name:', name) #name没有改变
print('names_ex:', names_ex)
![6bc35ed617209f593ebaa7669f6f348f.png](https://i-blog.csdnimg.cn/blog_migrate/3b91dd577031bdea79b8218849076df7.jpeg)
- 条件过滤
在推导式中可以做一些条件过滤
if表达式写在推导表达式的最末尾
names = ['zarten_1', 'zarten_2', 'zarten_3', 'python3']
names_ex = [name.title() for name in names if name.endswith('3')] #选择以“3”结尾的,并将首字母变为大写,
print('names_ex:', names_ex)
![fdbb09e182b2b72c380ca61aa7e52a26.png](https://i-blog.csdnimg.cn/blog_migrate/85c6d426091124636142b6d2603bd9b9.jpeg)
- for前面的转换式可以是一个函数
若转换式太过复杂,可以换成一个函数。
1.函数无返回值:最终生成的新的列表里面有元素,但全部为None
def fun(name):
print(name.title())
names = ['zarten_1', 'zarten_2', 'zarten_3', 'python3']
names_ex = [fun(name) for name in names] #将首字母变为大写,
print('names_ex:', names_ex)
![a67cbb41659becee6afde2c6c9bdcccc.png](https://i-blog.csdnimg.cn/blog_migrate/72440536a78f46dbefb6287f3ac0a81d.jpeg)
2.函数有返回值:最终生成的新的列表里面有元素,且全部是函数返回的值
def fun(name):
return name.title()
names = ['zarten_1', 'zarten_2', 'zarten_3', 'python3']
names_ex = [fun(name) for name in names] #将首字母变为大写,
print('names_ex:', names_ex)
![ce68889904365eaaeaefa99fdb003ddc.png](https://i-blog.csdnimg.cn/blog_migrate/2377997d31a0d8ab37cdcf9eac049aa3.png)
- 多层for循环(笛卡尔积)
多层for循环结果的先后顺序跟for的位置有关,可以看做如下:
for name in names:
for age in ages:
print({name:age})
具体代码如下:
names = ['zarten_1', 'zarten_2', 'zarten_3']
ages = [18, 19, 20]
names_ex = [{name:age} for name in names for age in ages]
print('names_ex:', names_ex)
#结果的顺序可以看做如下:
for name in names:
for age in ages:
print({name:age})
![a6fa2d2d151a3c805af0a322e409ad0a.png](https://i-blog.csdnimg.cn/blog_migrate/4557d4a65416b18eeacf532cbd24dac4.png)
若推导内部超过3层for循环,可读性就比较差了,此时最好是放弃推导式,使用for循环
可读性差的代码如下:
names = ['zarten_1', 'zarten_2', 'zarten_3']
ages = [18, 19, 20]
sexs = ['male', 'female']
names_ex = [[name,age,sex] for name in names for age in ages for sex in sexs]
print('names_ex:', names_ex)
生成器的写法
生成一个生成器的其中之一的写法是:列表推导中的[]换成()即可
names = ['zarten_1', 'zarten_2', 'zarten_3']
names_ex = (name.title() for name in names) #将首字母变为大写,生成器的写法
print('names_ex:', names_ex)
print(type(names_ex))
for name in names_ex:
print(name)
![412d897f1718cf4addc9a3f36c56b598.png](https://i-blog.csdnimg.cn/blog_migrate/93eb12025b1b6b9fcc71469f8dfadc91.jpeg)
字典推导
跟列表推导类似
info_dict = {
'zarten_1' : 18,
'zarten_2' : 19,
'zarten_3' : 20
}
new_info = {k.title():v+1 for k,v in info_dict.items()} #将key的首字母大写,且将value的数值加1
print(new_info)
![a09f6bd742639f095a2d6936505a7a0c.png](https://i-blog.csdnimg.cn/blog_migrate/94f72579b80838d645d96c40df7514ac.png)
不一定原始的数据类型是字典,也可以是其他类型的,只要最后表现形式是字典都是字典推导
names = ['zarten_1', 'zarten_2', 'zarten_3']
new_info = {name.title():18 for name in names}
print(new_info)
![436453e78e875ddb74c648c14c7da925.png](https://i-blog.csdnimg.cn/blog_migrate/587f812a9bc176aecbac755988dbf4a2.png)
key和value反转的例子
info_dict = {
'zarten_1' : 18,
'zarten_2' : 19,
'zarten_3' : 20
}
new_info = {v:k for k,v in info_dict.items()} #将key和value反转
print(new_info)
![f559d683411f28b072b2f1ebbfe9bbd9.png](https://i-blog.csdnimg.cn/blog_migrate/129d1a12b5433bd15b5520ddad4654b7.png)
关于条件过滤,多层循环等跟列表推导类似,这里将不再阐述
集合推导
集合推导只要使用一个大括号就可以了
names = ['zarten_1', 'zarten_2', 'zarten_3']
new_info = {name.title() for name in names} #首字母变为大写
print(new_info)
![ed6cf507b02e18177bc633b903b2cd5a.png](https://i-blog.csdnimg.cn/blog_migrate/c7032134e983c4746c3239ee2a51d1a9.jpeg)
同样,条件过滤,多层循环等一些共性也是跟列表推导类似的,这里不再阐述。