什么是列表推导式?

当一个for循环中代码比较简单的时候,往往都可以写成列表推导式,这样代码更加简洁、高效。举个栗子:

a = list(range(1, 11))  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 智障版
for index, value in enumerate(a):
    # a[index] = value + 1
    a[index] += 1

a  # [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]


# map()函数
list(map(lambda x: x + 1, a))  # [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

# 列表生成式
[i+1 for i in a]  #[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

配合if else的高级使用

仅配合if语句:

[i ** 2 for i in a if i % 2 == 0]
Out[5]: [0, 4, 16, 36, 64, 100]

配合if else语句:

首先复习一个三元表达式:

b = 2
c = 1 if b >= 3 else 0

c
Out[8]: 0

然后再来看:

[i ** 2 if i % 2 == 0 else i ** 3 for i in a ]
Out[9]: [0, 1, 4, 27, 16, 125, 36, 343, 64, 729, 100]

注意看,这个时候if else语句的位置已经在for语句之前了。

配合if elif else语句:

if elif else这个语句其实是不能实现的,但是可以绕一下,通过if else (if else)来实现(不加括号也是可以的,但是为了看起来更容易理解就加上了):

d = 2 if b >= 3 else (0 if b >= 0 else None)

d
Out[12]: 0

理解了上述语句之后,再来看列表推导式就不难了:

[i ** 2 if i % 2 == 0 else (i ** 3 if i % 3 == 0 else None) for i in a]
Out[13]: [0, None, 4, 27, 16, None, 36, None, 64, 729, 100]

配合函数的高级使用

当需要对for寻循环中的每一个i都需要进行比较复杂操作的时候,可以通过封装函数的方法来实现。

lambda匿名函数:

[(lambda x: x ** x)(i) for i in a]  # 计算列表a中每一个x数的x次方
Out[15]: [1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489, 10000000000]

配合lambda匿名函数加上if语句:

[(lambda x: x ** x)(i) for i in a if i % 2 == 0]  # 计算列表a中每一个x数的x次方
Out[16]: [1, 4, 256, 46656, 16777216, 10000000000]

配合自定义函数:

def calc(n):
    return n ** n


[(lambda x: x ** 0)(i) if i % 2 == 0 else calc(i) for i in a]
Out[19]: [1, 1, 1, 27, 1, 3125, 1, 823543, 1, 387420489, 1]

除了使用列表推导式+函数的方法来对列表中的每一个元素进行操作,还有一种简便的方法就是使用map()函数。

# map对象
map(lambda x: x ** 2, [i for i in a if i % 2 == 0])
Out[21]: <map at 0x253473af280>
# 配合lambda匿名函数
list(map(lambda x: x ** 2, [i for i in a if i % 2 == 0]))
Out[22]: [0, 4, 16, 36, 64, 100]
# 配合一般函数
list(map(calc, [i for i in a if i % 2 == 0]))
Out[24]: [1, 4, 256, 46656, 16777216, 10000000000]

需要注意的是,map()函数返回值是一个map对象,需要使用list()强制转化。

这里有个小疑问:Pandas里的apply()函数可以为其函数传递参数,但是map()函数好像没有这个功能。

import pandas as pd

def calc_n(x, n):
    return x ** n

a_s = pd.Series(a)

a_s.apply(calc_n, n = 10)  # 函数calc_的参数也可以通过apply()函数进行传递
Out[32]: 
0               0
1               1
2            1024
3           59049
4         1048576
5         9765625
6        60466176
7       282475249
8      1073741824
9      3486784401
10    10000000000
dtype: int64