“列表理解"是什么意思?和类似的意思?它是如何工作的,我该如何使用它?
问题描述
我有以下代码:
[x ** 2 for x in range(10)]
当我在 Python shell 中运行它时,它会返回:
When I run it in the Python shell, it returns:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
我已经搜索过,这似乎被称为 列表推导,类似地,似乎有 set/dict 推导和生成器表达式.但它是如何工作的呢?
I've searched and it seems this is called a list comprehension and similarly there seem to be set/dict comprehensions and generator expressions. But how does it work?
解决方案
来自文档:
列表推导式提供了一种创建列表的简洁方式.常见的应用是创建新列表,其中每个元素是应用于另一个序列或可迭代的每个成员的某些操作的结果,或者创建满足特定条件的那些元素的子序列.
List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.
<小时>
关于您的问题,列表推导与以下普通"Python 代码的作用相同:
About your question, the list comprehension does the same thing as the following "plain" Python code:
>>> l = []
>>> for x in range(10):
... l.append(x**2)
>>> l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
如何在一行中写出来?嗯...我们可以...可能...使用 map()
与 lambda
:
How do you write it in one line? Hmm...we can...probably...use map()
with lambda
:
>>> list(map(lambda x: x**2, range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
但是仅仅使用列表推导不是更清晰更简单吗?
But isn't it clearer and simpler to just use a list comprehension?
>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<小时>
基本上,我们可以用 x
做任何事情.不仅是 x**2
.比如运行一个x
的方法:
Basically, we can do anything with x
. Not only x**2
. For example, run a method of x
:
>>> [x.strip() for x in ('foo
', 'bar
', 'baz
')]
['foo', 'bar', 'baz']
或者使用 x
作为另一个函数的参数:
Or use x
as another function's argument:
>>> [int(x) for x in ('1', '2', '3')]
[1, 2, 3]
例如,我们也可以使用 x
作为 dict
对象的键.让我们看看:
We can also, for example, use x
as the key of a dict
object. Let's see:
>>> d = {'foo': '10', 'bar': '20', 'baz': '30'}
>>> [d[x] for x in ['foo', 'baz']]
['10', '30']
组合怎么样?
>>> d = {'foo': '10', 'bar': '20', 'baz': '30'}
>>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']]
[1, 3]
等等.
您还可以在列表推导中使用 if
或 if...else
.例如,您只需要 range(10)
中的奇数.你可以这样做:
You can also use if
or if...else
in a list comprehension. For example, you only want odd numbers in range(10)
. You can do:
>>> l = []
>>> for x in range(10):
... if x%2:
... l.append(x)
>>> l
[1, 3, 5, 7, 9]
啊,这太复杂了.下面的版本呢?
Ah that's too complex. What about the following version?
>>> [x for x in range(10) if x%2]
[1, 3, 5, 7, 9]
要使用 if...else
三元表达式,您需要将 if ... else ...
放在 x
之后,range(10)
之后的不是:
To use an if...else
ternary expression, you need put the if ... else ...
after x
, not after range(10)
:
>>> [i if i%2 != 0 else None for i in range(10)]
[None, 1, None, 3, None, 5, None, 7, None, 9]
<小时>
您听说过 嵌套列表理解强>?您可以将两个或多个for
放在一个列表推导中.例如:
Have you heard about nested list comprehension? You can put two or more for
s in one list comprehension. For example:
>>> [i for x in [[1, 2, 3], [4, 5, 6]] for i in x]
[1, 2, 3, 4, 5, 6]
>>> [j for x in [[[1, 2], [3]], [[4, 5], [6]]] for i in x for j in i]
[1, 2, 3, 4, 5, 6]
让我们谈谈第一部分,for x in [[1, 2, 3], [4, 5, 6]]
它给出了 [1, 2, 3]
和 [4, 5, 6]
.然后,for i in x
给出1
、2
、3
和4
,5
、6
.
Let's talk about the first part, for x in [[1, 2, 3], [4, 5, 6]]
which gives [1, 2, 3]
and [4, 5, 6]
. Then, for i in x
gives 1
, 2
, 3
and 4
, 5
, 6
.
警告:你总是需要把 for x in [[1, 2, 3], [4, 5, 6]]
before for i in x
:
>>> [j for j in x for x in [[1, 2, 3], [4, 5, 6]]]
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'x' is not defined
<小时>
我们还有set comprehensions、dict comprehensions和generator expressions.
集合推导和列表推导基本相同,只不过前者返回的是set而不是list:
set comprehensions and list comprehensions are basically the same, but the former returns a set instead of a list:
>>> {x for x in [1, 1, 2, 3, 3, 1]}
{1, 2, 3}
同理:
>>> set([i for i in [1, 1, 2, 3, 3, 1]])
{1, 2, 3}
一个dict理解 看起来像一个集合推导,但它使用 {key: value for key, value in ...}
或 {i: i for i in ...}
而不是 {i for i in ...}
.
A dict comprehension looks like a set comprehension, but it uses {key: value for key, value in ...}
or {i: i for i in ...}
instead of {i for i in ...}
.
例如:
>>> {i: i**2 for i in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
它等于:
>>> d = {}
>>> for i in range(5):
... d[i] = i**2
>>> d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
(i for i in range(5))
是否给出元组?不!这是一个生成器表达式.它返回一个生成器:
Does (i for i in range(5))
give a tuple? No!, it's a generator expression. Which returns a generator:
>>> (i for i in range(5))
<generator object <genexpr> at 0x7f52703fbca8>
同理:
>>> def gen():
... for i in range(5):
... yield i
>>> gen()
<generator object gen at 0x7f5270380db0>
您可以将其用作生成器:
And you can use it as a generator:
>>> gen = (i for i in range(5))
>>> next(gen)
0
>>> next(gen)
1
>>> list(gen)
[2, 3, 4]
>>> next(gen)
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
注意:如果您在函数中使用列表推导,如果该函数可以循环,则不需要 []
一个发电机.例如,sum()
:
Note: If you use a list comprehension inside a function, you don't need the []
if that function could loop over a generator. For example, sum()
:
>>> sum(i**2 for i in range(5))
30
相关(关于生成器):了解 Python 中的生成器.
相关文章