Osheep

时光不回头,当下最重要。

跟我读python3文档:021_列表推导式(5.1.3. List Comprehensions)

贯穿始终的理念:别废话,就是干!


往期回顾

  • 默认参数
  • 关键字参数
  • 匿名函数lambda
  • 列表的方法
  • del关键字

文档解读

python3文档第四小节链接地址:5. Data Structures

本章主要讲解5.1.3. List Comprehensions(列表推导式)5.1.4. Nested List Comprehensions(嵌套的列表推导式)这两个小节


5.1.3. List Comprehensions(列表推导式)

段落截取(一)

List comprehensions provide a concise way to create lists.

名词解释

  1. List comprehensions
    中文翻译:列表推导式
    这就是我们今天的主角,先记住这个名词,我们稍后具体讲解。

  2. concise
    中文翻译:简洁
    这个词是python语言的中心思想。在以后的学习中,要好好体会,好好思考。

段落大意

列表推导式提供了一种简洁的方式来创造列表。

注意:列表推导式的最终目的是生成列表!


接下来,我们直接看例子来学习列表推导式。

例子:

假设,我们要创建一个像这样的列表[0, 1, 4, 9, 16, 25, 36, 49, 64, 81],我们暂且称为平方数列表。你要如何做?

你可以选择的最直白的方式,就是在你的python交互环境中直接输入上面的列表,对不对?
但是,如果这个列表的数据更多呢?比如有100个,你要怎么办?

当数据量足够大时,就能体现出编程的重要性了。你可以写一个程序,然后输出这样一个列表。

先试试自己能不能写出这样一个程序~

提示:

  • for语句
  • append( )方法

答案:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

如果你成功实现了,恭喜你,说明你的自学能力很棒。如果没有实现,建议停下来,复习复习之前的章节。

那么如果用列表推导式如何实现呢?

>>> squares = [x**2 for x in range(10)]

对比一下,然后体会体会concise(简洁)这个词~

下面,我们来分析列表推导式的结构。

结构分析:

  1. 方括号
    既然叫列表推导式,自然少不了代表列表特色的方括号了。
  2. 表达式
    在这个例子里是x**2
  3. for循环
  • for 关键字
  • in 关键字

其实for循环后面还可以跟一些if语句用作条件判断,等碰到的时候在讲~

看明白了吗?
变量x从for循环中取值,然后在表达式中运算,运算结果直接存入列表。
过程就和我们最开始写的那个函数是一样的。
也就是说,列表推导式只是一种简写形式。
明白了吗?

注意:变量x仍旧存在于内存中。你可以用print( )函数打印它。
试试自己输出一个包含100个值的平方数列表~


如果觉得自己到目前为止都学会了,那么准备好,我们要加速了。
下面的内容会有一点难度,看不懂的话。。也得看!
还是那句老话,别废话,就是干!

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

能看的懂吗?看不懂没关系,先跟着我往下看。
此列表推导式的表达式有两个变量,x、y。
分别用两个for循环求得对应值,
并且通过if判断语句去除了x、y相等的情况。
注意:两个for循环是嵌套关系。

此列表推导式相当于下面的代码:

>>> a = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             a.append((x, y))
...
>>> a
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

注意两个for语句、一个if语句,他们三个的嵌套关系。或者说是运算顺序。

思考:

>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]

提示:(0,0)这种用圆括号括起来的形式叫做元组,他和列表的区别除了形式上括号的区别以外,还有最本质的一点:元组不可更改

此列表推导式的运算顺序可以概括为:取值,运算、运算。
能想明白运行结果吗?

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

此列表推导式的运算顺序可以概括为:取值,分解。
至于是从谁那里取值,从谁那里分级,分解之后又传递给了谁,则要自己思考了。
注意区分谁是表达式,谁是for循环。

如果看不明白,试试用复杂的嵌套语句的方式实现,在看看运算顺序。

如果你能想明白以上几个列表推导式的运算过程,那么,继续坐稳了,我们要上高速了!
如果不能看懂,建议今天先休息一下,明天在继续。


5.1.4. Nested List Comprehensions

段落截取(二)

The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.

段落大意

列表推导式的表达式可以是任意表达式,所以,这个表达式也可以是一个列表推导式。

我们直接看例子
有一个复杂列表

>>> matrix = [ [1, 2, 3, 4], [5, 6, 7, 8],[9, 10, 11, 12]]

这么看可能有点不明确,我们把书写方式调整下

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

这样看这个复杂列表就比较明确了吧。
在数学上,这是一个3X4的矩阵,现在,我们要把它变换为4X3的矩阵。

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

能区分开他们吗?

  • row[i]
    这是列表的下标取值
  • [row[i] for row in matrix]
    这是一个列表推导式,它被作为另一个列表推导式的表达式
  • for i in range(4)
    这是另一个列表推导式的for循环部分。

试试弄明白他的运算过程~
今天就讲到这里~

点赞