python多层循环列表推导

1 minute read

Published:

python多层循环列表推导。

python的列表推导应该都很熟悉了,举几个例子回顾一下。

1.用列表推导替代map

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alt = map(lambda x:x**2,a)
b = list(alt)

c = [x**2 for x in a]

assert b == c

2.用列表推导替代filter与map

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alt = map(lambda x:x**2,filter(lambda x:x%2==0,a)) #只对a中偶数做平方
b = [x**2 for x in a if x%2==0]
assert list(alt)==b

(tip:上面的代码可以继续优化,判断奇偶使用位运算速度更快)

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alt = map(lambda x:x**2,filter(lambda x:x&1==0,a)) #使用位运算判断
b = [x**2 for x in a if x&1==0]
assert list(alt)==b

上面代码的原理是:1的二进制最后一位为1,其余位为0,x如果是奇数,最后一位一定为1,x如果是偶数,最后一位一定为0,根据二进制与十进制的转换关系即可得到上述结论,因此x与1做位运算,便可以方便的判断奇偶。

3.当然还有字典推导、集合推导,使用字典推导、集合推导代替对应的构造函数

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alt_dict = dict(map(lambda x:(x,x**2),filter(lambda x:x&1==0,a)))
assert alt_dict=={x:x**2 for x in a if x&1==0}

alt_set=set(map(lambda x:x**3,filter(lambda x:x%3==0,a)))
assert alt_set=={x**3 for x in a if x%3==0}

python的多层循环列表推导

1.二维列表转换为一维列表

matrix = [[1,2,3],[4,5,6],[7,8,9]]
flat = [x for row in matrix for x in row]
print(flat)

2.二维列表按元素平方

matrix = [[1,2,3],[4,5,6],[7,8,9]]
squared_matrix = [[x**2 for x in row] for row in matrix]
print(squared_matrix)

注意多维的列表推导与一维的顺序不一样,转换为一维时首先循环row in matrix,但是二维时首先在第二层列表里循环x in row。

3.带条件的多层循环推导

例如将matrix中是偶数且大于4的数挑出并构建为一维列表。

matrix = [[1,2,3],[4,5,6],[7,8,9]]
flat = [x for row in matrix for x in row if x&1==0 if x>4]
print(flat)

两个if连用代表两个if的条件是and关系,所以上面的代码也可以写成

flat = [x for row in matrix for x in row if not x&1 and x>4]

(tip:if x&1==0 也可以写成 if not x&1,not在python中为一个运算符,并不是if not)

4.也可以嵌套3层甚至4层循环,但是这样做,代码清晰性就不如直接用常规方法写多层for了