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

5.6 KiB
Raw Permalink Blame History

Python 列表理解:示例教程

原文:https://python.land/deep-dives/list-comprehension

数学中有一个概念叫做集合构造符号也叫集合理解。受这一原则的启发Python 提供了列表理解。事实上Python 列表理解是该语言的定义特性之一。它允许我们创建简洁、可读的代码,胜过那些丑陋的替代方法,比如 for 循环或使用map()

我们先来看看最广为人知的类型:列表理解。一旦我们很好地掌握了它们是如何工作的,你还将学习集合理解和词典理解。

目录

什么是列表理解?

Python 列表理解是一种语言结构。它用于基于现有列表创建一个 Python 列表。听起来有点模糊,但在几个例子之后,那‘啊哈!’相信我,那一刻会到来的。

列表理解的基本语法是:

[ <expression> for item in list if <conditional> ]

“如果”部分是可选的,您很快就会发现。然而,我们确实需要一个列表来开始。或者,更具体地说,任何可以被迭代的东西。我们将使用 Python 的range()函数,它是一种特殊类型的迭代器,称为生成器:它在每次迭代中生成一个新数字。

列表理解的例子

理论到此为止,让我们看看最基本的例子,我鼓励你启动一个 Python REPL 来亲自尝试一下:

>>> [x for x in range(1, 5)]
[1, 2, 3, 4]

一些观察结果:

  • expression部分就是x
  • 我们使用 range()函数代替列表。我们也可以使用[1, 2, 3, 4],但是使用 range()更有效,对于更长的范围需要更少的输入。

结果是从 range() 获得的元素列表。不是很有用,但是我们确实创建了我们的第一个 Python 列表理解。我们也可以使用:

>>> list(range(1,5))
[1, 2, 3, 4]

因此,让我们加入 if 语句,使它更有用:

>>> [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. It's much appreciated and allows me to keep working on this site!

到目前为止,我们的expression(x)真的很简单。为了让这一点非常清楚,expression可以是任何有效的 Python 代码,并被认为是一个表达式。示例:

>>> [x + 4 for x in [10, 20]]
[14, 24]

这个表达式给 x 加四,还是挺简单的。但是我们也可以做一些更复杂的事情,比如用x作为参数调用函数:

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 表达式,也可以是另一个列表理解。当您想要创建矩阵时,这很有用:

>>> 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]]

或者,如果您想要展平前一个矩阵:

>>> [value for sublist in m for value in sublist]
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]

相同,但多了一些空格,使这一点更清楚:

>>> [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 循环。如果你来自 C 风格的语言,比如 Java你会倾向于使用 for 循环。尽管这不是世界末日,但是您应该知道列表理解更具性能,并且被认为是更好的编码风格。

其他理解

如果有列表理解,为什么不创建字典理解呢?或者集合理解呢?正如你所料,两者都存在。

集合理解

理解一个 Python 集合的语法没有太大的不同。我们只是用花括号代替方括号:

{ <expression> for item in set if <conditional> }

例如:

>>> {s for s in range(1,5) if s % 2}
{1, 3}

词典释义

字典需要一个键和值。否则,又是同样的把戏:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}

唯一的区别是我们在expression 部分定义了键和值。