第8条:不要使用含有两个以上表达式的列表推导
核心知识点:
1.列表推导式支持多级循环,每一级循环也支持多项条件。
2.列表推导式的读取按照从左往右的顺序来评估,如果有括号,括号里面的优先读取。
3.超过两个表达式的列表推导式非常不好理解,应该尽量避免。
列表推导式除了基本的用法之外,也支持多重循环。
例如,要把一个矩阵(也就是含有列表的列表,即二维列表)简化成一维列表,使原来的每个单元格都成为新列表中的元素。
这个功能采用包含两个for 表达式的列表推导式即可,这些for表达式会按照从左至右的顺序来评估。
>>> list1 = [[1,2,3],[4,5,6],[7,8,9]] >>> list2 = [x for row in list1 for x in row] >>> print(list2) [1, 2, 3, 4, 5, 6, 7, 8, 9]
上面的例子简单易懂,也是多重循环的合理用法,但是如果我们要对矩阵中的每个单元格取平方,那就会稍微麻烦一点。
>>> list3 = [[x**2 for x in row] for row in list1] #有括号先计算括号里面的 >>> print(list3) [[1, 4, 9], [16, 25, 36], [49, 64, 81]]
如果表达式里面还有一层循环,那么推导式就会变得很长,这时必须把它分成多行来写,才能看的清楚一些。例如:
>>> a = [ ... [[1,2,3],[4,5,6]], ... [[7,8,9],[10,11,12]], ... [[13,14,15],[16,17,18]] ... ]
使用列表推导不好做,此时使用循环还简单一点。
>>> a1 = [] >>> for one in a: ... for two in one: ... for x in two: ... a1.append(x) ... >>> print(a1) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
列表推导式还支持多个if条件。处在同一级别中的多项条件,彼此之间默认形成and表达式。
例如,要从数字列表中选出大于4的偶数,那么下面两种推导方式等价。
>>> a = [1,2,3,4,5,6,7,8,9,10] >>> b = [x for x in a if x > 4 and x % 2 == 0] >>> c = [x for x in a if x > 4 if x % 2 == 0] >>> print(b) [6, 8, 10] >>> print(c) [6, 8, 10]
每一级循环的for表达式后面都可以指定条件,但是代码会非常难懂。
在列表推导式中,最好不要使用两个以上的表达式。可以使用两个条件、两个循环或一个条件搭配一个循环。
如果写的代码比这还要复杂,那就应该使用普通的if和for语句,并编写辅助函数。