geekdoc-python-zh/docs/pythonland/36.md

148 lines
5.6 KiB
Markdown
Raw Permalink Normal View History

2024-03-03 22:54:39 +08:00
# Python 列表理解:示例教程
> 原文:[https://python.land/deep-dives/list-comprehension](https://python.land/deep-dives/list-comprehension)
数学中有一个概念叫做[集合构造符号](https://en.m.wikipedia.org/wiki/Set-builder_notation)也叫集合理解。受这一原则的启发Python 提供了列表理解。事实上Python 列表理解是该语言的定义特性之一。它允许我们创建简洁、可读的代码,胜过那些丑陋的替代方法,比如 for 循环或使用`map()`。
我们先来看看最广为人知的类型:列表理解。一旦我们很好地掌握了它们是如何工作的,你还将学习[集合理解](https://python.land/python-data-types/python-set-the-why-and-how-with-example-code)和词典理解。
目录
* 什么是列表理解?
* [列表理解的例子](#Examples_of_list_comprehensions "Examples of list comprehensions")
* [更高级的例子](#More_advanced_examples "More advanced examples")
* [其他理解](#Other_comprehensions "Other comprehensions")
## 什么是列表理解?
Python 列表理解是一种语言结构。它用于基于现有列表创建一个 [Python 列表](https://python.land/python-data-types/python-list)。听起来有点模糊,但在几个例子之后,那‘啊哈!’相信我,那一刻会到来的。
列表理解的基本语法是:
```py
[ <expression> for item in list if <conditional> ]
```
“如果”部分是可选的,您很快就会发现。然而,我们确实需要一个列表来开始。或者,更具体地说,任何可以被[迭代](https://python.land/deep-dives/python-iterator)的东西。我们将使用 Python 的`range()`函数,它是一种特殊类型的迭代器,称为生成器:它在每次迭代中生成一个新数字。
## 列表理解的例子
理论到此为止,让我们看看最基本的例子,我鼓励你启动一个 [Python REPL](https://python.land/introduction-to-python/the-repl) 来亲自尝试一下:
```py
>>> [x for x in range(1, 5)]
[1, 2, 3, 4]
```
一些观察结果:
* `expression`部分就是`x`
* 我们使用 range()函数代替列表。我们也可以使用`[1, 2, 3, 4]`,但是使用 range()更有效,对于更长的范围需要更少的输入。
结果是从 *range()* 获得的元素列表。不是很有用,但是我们确实创建了我们的第一个 Python 列表理解。我们也可以使用:
```py
>>> list(range(1,5))
[1, 2, 3, 4]
```
因此,让我们加入 if 语句,使它更有用:
```py
>>> [x for x in range(1,10) if x % 2 == 0]
[2, 4, 6, 8]
```
*if* 部分的作用类似于一个过滤器。如果【T2 if 之后的条件解析为真,则包含该项目。如果它解析为 False它将被忽略。这样我们可以使用列表理解只得到偶数。
Thank you for reading my tutorials. I write these in my free time, and it requires a lot of time and effort. I use ads to keep writing these *free* articles, I hope you understand! **Support me by disabling your adblocker on my website** or, alternatively, **[buy me some coffee](https://www.buymeacoffee.com/pythonland)**. It's much appreciated and allows me to keep working on this site!
到目前为止,我们的`expression`(`x`)真的很简单。为了让这一点非常清楚,`expression`可以是任何有效的 Python 代码,并被认为是一个表达式。示例:
```py
>>> [x + 4 for x in [10, 20]]
[14, 24]
```
这个表达式给 x 加四,还是挺简单的。但是我们也可以做一些更复杂的事情,比如用`x`作为参数调用函数:
```py
def some_function(a):
return (a + 5) / 2
m = [some_function(x) for x in range(8)]
print(m)
# [2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0]
```
## 更高级的例子
你掌握了基础;恭喜你。让我们继续看一些更高级的例子。
### 嵌套列表理解
如果`expression`可以是任何有效的 Python 表达式,也可以是另一个列表理解。当您想要创建矩阵时,这很有用:
```py
>>> m = [[j for j in range(3)] for i in range(4)]
>>> m
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
```
或者,如果您想要展平前一个矩阵:
```py
>>> [value for sublist in m for value in sublist]
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
```
相同,但多了一些空格,使这一点更清楚:
```py
>>> [value
for sublist in m
for value in sublist]
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
```
第一部分循环遍历矩阵`m`。第二部分遍历每个向量中的元素。
### 列表理解的替代方案
Python 语言可以不需要理解;它看起来就没那么漂亮了。使用像`map()`和`reduce()`这样的函数式编程函数可以做列表理解所能做的一切。
另一种选择是使用 [for 循环](https://python.land/introduction-to-python/python-for-loop)。如果你来自 C 风格的语言,比如 Java你会倾向于使用 for 循环。尽管这不是世界末日,但是您应该知道列表理解更具性能,并且被认为是更好的编码风格。
## 其他理解
如果有列表理解,为什么不创建字典理解呢?或者集合理解呢?正如你所料,两者都存在。
### 集合理解
理解一个 [Python 集合](https://python.land/python-data-types/python-set-the-why-and-how-with-example-code)的语法没有太大的不同。我们只是用花括号代替方括号:
```py
{ <expression> for item in set if <conditional> }
```
例如:
```py
>>> {s for s in range(1,5) if s % 2}
{1, 3}
```
### 词典释义
字典需要一个键和值。否则,又是同样的把戏:
```py
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
```
唯一的区别是我们在`expression` 部分定义了键和值。