“清单理解”有什么作用。和类似的意思?它如何工作,如何使用它?

发布于 2025-02-09 20:34:22 字数 276 浏览 3 评论 0 原文

我有以下代码:

[x ** 2 for x in range(10)]

当我在python shell中运行它时,它返回:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

我已经搜索了,看来这被称为 list consection ,同样似乎有设置/dict enlastions and dict enlastions和生成器表达。但是它如何工作?

I have the following code:

[x ** 2 for x in range(10)]

When I run it in the Python shell, it returns:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

能怎样 2025-02-16 20:34:22

来自 文档

列表综合提供了一种创建列表的简洁方法。常见的应用程序是在每个元素上都是应用于其他序列或迭代序列的每个成员的结果的新列表,或者创建满足特定条件的元素的子序列。


关于您的问题,列表理解与以下“普通” python代码相同的事情:

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

如何将其写成一行?嗯...我们可以...可能...使用 map( )

>>> list(map(lambda x: x**2, range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

但是,只使用列表理解越清楚,更简单吗?

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

基本上,我们可以使用 x 来做任何事情。不仅 x ** 2 。例如,运行 x 的方法:

>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')]
['foo', 'bar', 'baz']

或使用 x 作为另一个函数的参数:

>>> [int(x) for x in ('1', '2', '3')]
[1, 2, 3]

例如,我们还可以使用 x 作为密钥 dict 对象的of。让我们看看:

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

等等。


您也可以在列表理解中使用或如果... else 在列表理解中使用。例如,您只需要范围(10)中的奇数数字。您可以做:

>>> l = []
>>> for x in range(10):
...     if x%2:
...         l.append(x)
>>> l
[1, 3, 5, 7, 9]

啊,太复杂了。那以下版本呢?

>>> [x for x in range(10) if x%2]
[1, 3, 5, 7, 9]

要使用,如果... else 三元表达式,您需要将放置... else ... 之后 x <代码>范围之后(10):

>>> [i if i%2 != 0 else None for i in range(10)]
[None, 1, None, 3, None, 5, None, 7, None, 9]

您是否听说过 嵌套列表理解 ?您可以在一个列表理解中将的两个或多个放在一个中。例如:

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

让我们谈谈第一部分,<代码> x在[[1,2,3],[4,5,6]] 中给出 [1,2,3] < /code>和 [4,5,6] 。然后,对于x 给出 1 2 , 3 4 5 6

警告:您始终需要在[[1,2,3],[4,5,6]] 对于i在x 中的i:

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

我们还设置了设置综合 dict enlastions Generator Expressions

设置综合和列表综合基本上是相同的,但是前者返回a set 而不是 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}

: a dict classence 看起来像设置的理解,但它使用 {键:键的值,in ...} {i:i in ... in ...} 而不是 {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在范围(5)中i)给出 tuple ?不!返回 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>

您可以将其用作生成器:

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

注意:如果您在函数内使用列表clastension ,您不需要 [] 如果该功能可以通过生成器循环。例如, sum()

>>> sum(i**2 for i in range(5))
30

< strong>相关(关于生成器):了解Python中的生成器

From the documentation:

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.


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]

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]

Basically, we can do anything with x. Not only x**2. For example, run a method of x:

>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')]
['foo', 'bar', 'baz']

Or use x as another function's argument:

>>> [int(x) for x in ('1', '2', '3')]
[1, 2, 3]

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

How about a combination?

>>> d = {'foo': '10', 'bar': '20', 'baz': '30'}
>>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']]
[1, 3]

And so on.


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]

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]

Have you heard about nested list comprehension? You can put two or more fors 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]

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.

Warning: You always need put 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

We also have set comprehensions, dict comprehensions, and generator expressions.

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}

It's the same as:

>>> set([i for i in [1, 1, 2, 3, 3, 1]])
{1, 2, 3}

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 ...}.

For example:

>>> {i: i**2 for i in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

And it equals:

>>> d = {}
>>> for i in range(5):
...     d[i] = i**2
>>> d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

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>

It's the same as:

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

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

Related (about generators): Understanding Generators in Python.

你对谁都笑 2025-02-16 20:34:22

有列表,字典和设置综合,但没有元组综合(尽管确实探索了“生成器表达”)。

他们解决了python中传统循环是陈述(不要返回任何内容)而不是返回值的表达式的问题。

它们不是解决每个问题的解决方案,并且可以被重写为传统循环。当需要维护状态时,它们变得尴尬&amp;在迭代之间进行了更新。

它们通常由:

[<output expr> <loop expr <input expr>> <optional predicate expr>]

但可以以许多有趣且奇怪的方式扭曲。

它们可以类似于传统 map() filter()仍然存在于Python中并继续使用的操作。

做得好时,它们具有很高的满足商。

There are list, dictionary, and set comprehensions, but no tuple comprehensions (though do explore "generator expressions").

They address the problem that traditional loops in Python are statements (don't return anything) not expressions which return a value.

They are not the solution to every problem and can be rewritten as traditional loops. They become awkward when state needs to be maintained & updated between iterations.

They typically consist of:

[<output expr> <loop expr <input expr>> <optional predicate expr>]

but can be twisted in lots of interesting and bizarre ways.

They can be analogous to the traditional map() and filter() operations which still exist in Python and continue to be used.

When done well, they have a high satisfaction quotient.

青丝拂面 2025-02-16 20:34:22

如果您喜欢一种更视觉的方法来弄清楚发生了什么,那么也许这会有所帮助:

# for the example in the question...

y = []
for x in range(10):
    y += [x**2]

# is equivalent to...

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

# for a slightly more complex example, it is useful
# to visualize  where the various x's end up...

a = [1,2,3,4]
b = [3,4,5,6]
c = []

for x in a:
          if x in b:
                  c += [x]
#   \         \        /
#    \    _____\______/
#     \  /      \
#      \/        \
#      /\         \
#     /  \         \
#    /    \         \
c = [x for x in a if x in b]

print(c)

...产生输出 [3,4]

If you prefer a more visual way of figuring out what's going on then maybe this will help:

# for the example in the question...

y = []
for x in range(10):
    y += [x**2]

# is equivalent to...

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

# for a slightly more complex example, it is useful
# to visualize  where the various x's end up...

a = [1,2,3,4]
b = [3,4,5,6]
c = []

for x in a:
          if x in b:
                  c += [x]
#   \         \        /
#    \    _____\______/
#     \  /      \
#      \/        \
#      /\         \
#     /  \         \
#    /    \         \
c = [x for x in a if x in b]

print(c)

...produces the output [3, 4]

狂之美人 2025-02-16 20:34:22

最近,我看到了很多关于清单综合工作方式的困惑(在其他问题和同事上)。数学教育的一段时间可以帮助为什么语法是这样的,以及清单的综合性真正含义。

语法

最好将列表的综合视为在集合/集合上的谓词,就像我们在数学中使用集合构建器符号一样。对我来说,符号实际上很自然,因为我拥有数学学位。但是忘了我,吉多·范·罗斯姆(Python的发明者)拥有数学硕士学位,并具有数学背景。

设置构建器符号速效课程

这是设置构建器符号的工作方式的(非常基础):

“在此处输入图像说明”

所以,此集合构建器表示法代表严格肯定的数字集(即 [1,2, 3,4,...] )。

混淆点

1) set构建器符号中的谓词过滤器仅指定我们要保留的项目,并列出理解谓词做同样的事情。您不必在省略项目,除非谓词包括在内,否则将省略它们。空谓词(即最后没有条件)包括给定集合中的所有项目。

2) set Builder符号中的谓词过滤器最终出现在列表综合中。(某些)初学者认为 [x&lt; 5对于x范围(10)] 将为他们提供列表 [0,1,2,3,4] ,而实际上它输出是真的,正确,正确,错误,错误,false,false,false] 。我们获得输出 [真实,真实,真实,真实,真实,错误,false,false,false,false] ,因为我们要求Python评估 x&lt; 5 <代码>范围(10)中的所有项目。没有谓词意味着我们从集合中获取所有内容(就像在集合构建器符号中一样)。

如果您在使用列表综合的同时将设置的构建器符号保持在脑海中,则它们更容易吞咽。

hth!

I've seen a lot of confusion lately (on other SO questions and from coworkers) about how list comprehensions work. A wee bit of math education can help with why the syntax is like this, and what list comprehensions really mean.

The syntax

It's best to think of list comprehensions as predicates over a set/collection, like we would in mathematics by using set builder notation. The notation actually feels pretty natural to me, because I hold an undergrad degree in Mathematics. But forget about me, Guido van Rossum (inventor of Python) holds a masters in Mathematics and has a math background.

Set builder notation crash course

Here's the (very basics) of how set builder notation works:

enter image description here

So, this set builder notation represents the set of numbers that are strictly positive (i.e. [1,2,3,4,...]).

Points of confusion

1) The predicate filter in set builder notation only specifies which items we want to keep, and list comprehension predicates do the same thing. You don't have to include special logic for omitting items, they are omitted unless included by the predicate. The empty predicate (i.e. no conditional at the end) includes all items in the given collection.

2) The predicate filter in set builder notation goes at the end, and similarly in list comprehensions. (some) Beginners think something like [x < 5 for x in range(10)] will give them the list [0,1,2,3,4], when in fact it outputs [True, True, True, True, True, False, False, False, False, False]. We get the output [True, True, True, True, True, False, False, False, False, False] because we asked Python to evaluate x < 5 for all items in range(10). No predicate implies that we get everything from the set (just like in set builder notation).

If you keep set builder notation in the back of your mind while using list comprehensions, they're a bit easier to swallow.

HTH!

妄司 2025-02-16 20:34:22

简介

列表理解是在Python中创建列表的高级,声明的方法。综合的主要好处是可读性和可维护性。很多人发现它们非常可读,甚至从未见过它们的开发人员通常都可以正确猜测它的含义。

# Snippet 1
squares = [n ** 2 for n in range(5)]

# Snippet 2
squares = []
for n in range(5):
    squares.append(n ** 2)

两个代码的两个片段都将产生 squares 等于 [0,1,4,9,16]

请注意,在第一个片段中,您的类型是在声明您想要的列表,而第二个则指定如何创建它。这就是为什么理解是高级和声明的原因。

语法

[EXPRESSION for VARIABLE in SEQUENCE]

表达式是任何python表达式,但通常具有一些变量是典型的。此变量在变量字段中说明。 sequence 定义值列举的值的来源。

考虑片段1, [n ** 2 for n范围(5)]

  • expression is n ** 2
  • variable /code> is n
  • sequence range> range(5)

请注意,如果您检查 Squares 的类型,您将了解列表理解只是一个常规列表:

>>> type(squares)
<class 'list'>

更多关于表达式

表达式可以是将任何降低到值的事物:

  • 算术表达式,例如 n ** 2 + 3 * n + 1 < /code>
  • 一个函数调用,例如 f(n)使用 n 作为变量的
  • slice操作,例如 s [::- 1]
  • 方法>方法调用<代码> bar.foo()
  • ...

一些示例:

>>> [2 * x + 3 for x in range(5)]
[3, 5, 7, 9, 11]
>>> [abs(num) for num in range(-5, 5)]
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
>>> animals = ['dog', 'cat', 'lion', 'tiger']
>>> [animal.upper() for animal in animals]
['DOG', 'CAT', 'LION', 'TIGER']

过滤:

最终列表中元素的顺序由 sequence 的顺序确定。但是,您可以过滤出添加的元素,如果子句:

[EXPRESSION for VARIABLE in SEQUENCE if CONDITION]

条件是评估 true false> false 的表达式。 。从技术上讲,条件不必依赖于变量,但通常使用它。

示例:

>>> [n ** 2 for n in range(5) if n % 2 == 0]
[0, 4, 16]
>>> animals = ['dog', 'cat', 'lion', 'tiger']
>>> [animal for animal in animals if len(animal) == 3]
['dog', 'cat']

另外,请记住,Python允许您编写除列表以外的其他综合:

  • 字典综合
  • 设置综合

Introduction

A list comprehension is a high level, declarative way to create a list in Python. The main benefits of comprehensions are readability and maintainability. A lot of people find them very readable, and even developers who have never seen them before can usually guess correctly what it means.

# Snippet 1
squares = [n ** 2 for n in range(5)]

# Snippet 2
squares = []
for n in range(5):
    squares.append(n ** 2)

Both snippets of code will produce squares to be equal to [0, 1, 4, 9, 16].

Notice that in the first snippet, what you type is declaring what kind of list you want, while the second is specifying how to create it. This is why a comprehension is a high-level and declarative.

Syntax

[EXPRESSION for VARIABLE in SEQUENCE]

EXPRESSION is any Python expression, but it is typical to have some variable in it. This variable is stated in VARIABLE field. SEQUENCE defines the source of values the variable enumerates through.

Considering Snippet 1, [n ** 2 for n in range(5)]:

  • EXPRESSION is n ** 2
  • VARIABLE is n
  • SEQUENCE is range(5)

Notice that if you check the type of squares you will get that the list comprehension is just a regular list:

>>> type(squares)
<class 'list'>

More about EXPRESSION

The expression can be anything that reduces to a value:

  • Arithmetic expressions such as n ** 2 + 3 * n + 1
  • A function call like f(n) using n as variable
  • A slice operation like s[::-1]
  • Method calls bar.foo()
  • ...

Some examples:

>>> [2 * x + 3 for x in range(5)]
[3, 5, 7, 9, 11]
>>> [abs(num) for num in range(-5, 5)]
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
>>> animals = ['dog', 'cat', 'lion', 'tiger']
>>> [animal.upper() for animal in animals]
['DOG', 'CAT', 'LION', 'TIGER']

Filtering:

The order of elements in the final list is determined by the order of SEQUENCE. However, you can filter out elements adding an if clause:

[EXPRESSION for VARIABLE in SEQUENCE if CONDITION]

CONDITION is an expression that evaluates to True or False. Technically, the condition doesn't have to depend upon VARIABLE, but it typically uses it.

Examples:

>>> [n ** 2 for n in range(5) if n % 2 == 0]
[0, 4, 16]
>>> animals = ['dog', 'cat', 'lion', 'tiger']
>>> [animal for animal in animals if len(animal) == 3]
['dog', 'cat']

Also, remember that Python allows you to write other kinds of comprehensions other than lists:

  • dictionary comprehensions
  • set comprehensions
一花一树开 2025-02-16 20:34:22

对于那些寻找A 嵌套的内联操作员

[(i,j) for i in range(8) for j in range(8)]

它等于 itertools.products.product

from itertools import product

list(product(range(8), range(8)))

对于其他上下文,这等同于以下嵌套循环:

results = []
for i in range(8):
    for j in range(8):
        coord = (i, j)
        results.append(coord)

For those looking for a nested inline operator:

[(i,j) for i in range(8) for j in range(8)]

Which is equivalent to itertools.product:

from itertools import product

list(product(range(8), range(8)))

For additional context, this is equivalent to the following nested loops:

results = []
for i in range(8):
    for j in range(8):
        coord = (i, j)
        results.append(coord)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文