Python for-in 循环前面有一个变量

发布于 2024-11-17 06:09:01 字数 111 浏览 2 评论 0原文

我看到一些代码,例如:

foo = [x for x in bar if x.occupants > 1]

这是什么意思,它是如何工作的?

I saw some code like:

foo = [x for x in bar if x.occupants > 1]

What does this mean, and how does it work?

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

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

发布评论

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

评论(5

余生共白头 2024-11-24 06:09:01

当前的答案很好,但不要谈论它们如何只是语法糖到某种模式我们已经习惯了。

让我们从一个例子开始,假设我们有 10 个数字,并且我们想要大于 5 的数字的子集。

>>> numbers = [12, 34, 1, 4, 4, 67, 37, 9, 0, 81]

对于上述任务,下面的方法彼此完全相同,从最冗长到简洁、可读且Pythonic

方法 1

result = []
for index in range(len(numbers)):
    if numbers[index] > 5:
        result.append(numbers[index])
print result  #Prints [12, 34, 67, 37, 9, 81]

方法 2(稍微简洁,for-in 循环)

result = []
for number in numbers:
    if number > 5:
        result.append(number)
print result  #Prints [12, 34, 67, 37, 9, 81]

方法 3(输入列表理解)

result = [number for number in numbers if number > 5]

或更一般地说:

[function(number) for number in numbers if condition(number)]

其中:

  • function(x) 接受一个 x 并将其转换为有用的东西(例如:x*x
  • if condition(x ) 返回任何 False-y 值(False、None、空字符串、空列表等),然后当前迭代将被跳过(认为继续)。如果函数返回非 False-y 值,则当前值将进入最终结果数组(并经历上面的转换步骤)。

要以稍微不同的方式理解语法,请查看下面的“奖励”部分。

有关更多信息,请按照所有其他答案链接的教程进行操作:列表理解


Bonus

(有点不符合Python风格,但为了完整起见把它放在这里)

上面的例子可以写成:

result = filter(lambda x: x > 5, numbers)

上面的一般表达式可以写成:

result = map(function, filter(condition, numbers)) #result is a list in Py2

The current answers are good, but do not talk about how they are just syntactic sugar to some pattern that we are so used to.

Let's start with an example, say we have 10 numbers, and we want a subset of those that are greater than, say, 5.

>>> numbers = [12, 34, 1, 4, 4, 67, 37, 9, 0, 81]

For the above task, the below approaches below are totally identical to one another, and go from most verbose to concise, readable and pythonic:

Approach 1

result = []
for index in range(len(numbers)):
    if numbers[index] > 5:
        result.append(numbers[index])
print result  #Prints [12, 34, 67, 37, 9, 81]

Approach 2 (Slightly cleaner, for-in loops)

result = []
for number in numbers:
    if number > 5:
        result.append(number)
print result  #Prints [12, 34, 67, 37, 9, 81]

Approach 3 (Enter List Comprehension)

result = [number for number in numbers if number > 5]

or more generally:

[function(number) for number in numbers if condition(number)]

where:

  • function(x) takes an x and transforms it into something useful (like for instance: x*x)
  • if condition(x) returns any False-y value (False, None, empty string, empty list, etc ..) then the current iteration will be skipped (think continue). If the function return a non-False-y value then the current value makes it to the final resultant array (and goes through the transformation step above).

To understand the syntax in a slightly different manner, look at the Bonus section below.

For further information, follow the tutorial all other answers have linked: List Comprehension


Bonus

(Slightly un-pythonic, but putting it here for sake of completeness)

The example above can be written as:

result = filter(lambda x: x > 5, numbers)

The general expression above can be written as:

result = map(function, filter(condition, numbers)) #result is a list in Py2
二手情话 2024-11-24 06:09:01

这是一个 列表理解

foo 将是一个过滤后的 bar 列表,其中包含具有属性 habitants > 的对象1

bar 可以是 listsetdict 或任何其他可迭代

对象 下面是一个示例来说明

>>> class Bar(object):
...   def __init__(self, occupants):
...     self.occupants = occupants
... 
>>> bar=[Bar(0), Bar(1), Bar(2), Bar(3)]
>>> foo = [x for x in bar if x.occupants > 1]
>>> foo
[<__main__.Bar object at 0xb748516c>, <__main__.Bar object at 0xb748518c>]

So foo有 2 个 Bar 对象,但是我们如何检查它们是哪一个呢?让我们向 Bar 添加一个 __repr__ 方法,以便提供更多信息

>>> Bar.__repr__=lambda self:"Bar(occupants={0})".format(self.occupants)
>>> foo
[Bar(occupants=2), Bar(occupants=3)]

It's a list comprehension

foo will be a filtered list of bar containing the objects with the attribute occupants > 1

bar can be a list, set, dict or any other iterable

Here is an example to clarify

>>> class Bar(object):
...   def __init__(self, occupants):
...     self.occupants = occupants
... 
>>> bar=[Bar(0), Bar(1), Bar(2), Bar(3)]
>>> foo = [x for x in bar if x.occupants > 1]
>>> foo
[<__main__.Bar object at 0xb748516c>, <__main__.Bar object at 0xb748518c>]

So foo has 2 Bar objects, but how do we check which ones they are? Lets add a __repr__ method to Bar so it is more informative

>>> Bar.__repr__=lambda self:"Bar(occupants={0})".format(self.occupants)
>>> foo
[Bar(occupants=2), Bar(occupants=3)]
祁梦 2024-11-24 06:09:01

由于问题的编程部分已由其他人完全回答,因此很高兴了解它与数学的关系(集合论< /a>)。实际上它是Set 构建器表示法的 Python 实现

通过规范公理定义集合:

B = { x є A : S(x) }

英文翻译:B是一个集合,其成员是从A中选出的,
所以 BA 的子集 (B ⊂ A),其中特征由
函数 S 成立:S(x) == True

使用列表理解定义B

B = [x for x in A if S(x)]

因此,要使用 构建 B列表理解B的成员(用x表示)是从集合A中选择的,其中S(x ) == True (包含条件)。

注意:返回布尔值的函数 S 称为 predicate

Since the programming part of question is fully answered by others it is nice to know its relation to mathematics (set theory). Actually it is the Python implementation of Set builder notation:

Defining a set by axiom of specification:

B = { x є A : S(x) }

English translation: B is a set where its members are chosen from A,
so B is a subset of A (B ⊂ A), where characteristic(s) specified by
function S holds: S(x) == True

Defining B using list comprehension:

B = [x for x in A if S(x)]

So to build B with list comprehension, member(s) of B (denoted by x) are chosen from set A where S(x) == True (inclusion condition).

Note: Function S which returns a boolean is called predicate.

这将返回一个列表,其中包含 bar 中占用者 > 的所有元素。 1.

This return a list which contains all the elements in bar which have occupants > 1.

霊感 2024-11-24 06:09:01

据我所知,它应该工作的方式是,它检查列表“bar”是否为空(0)或通过 x.occupants 由单例(1)组成,其中 x 是列表栏中定义的项目,可能具有居住者的特征。因此 foo 被调用,在列表中移动,然后返回所有通过检查条件(即 x.occupant)的项目。

在像 Java 这样的语言中,您可以构建一个名为“x”的类,然后将“x”对象分配给数组或类似的数组。 X 将有一个名为“占用者”的字段,并且将使用 x.ocupants 方法检查每个索引,该方法将返回分配给占用者的号码。如果该方法返回大于 1(我们假设这里的 int 作为部分占用者是奇怪的。) foo 方法(在数组或类似的问题上调用。)然后将返回一个数组或类似的数组,如 foo 方法中定义的那样对于这个容器数组或者你有什么。返回数组的元素将是第一个数组事物中符合“大于 1”条件的“x”对象。

Python 具有通过列表理解的内置方法,可以以更简洁和简化的方式处理此问题。我没有实现两个完整的类和多个方法,而是编写了一行代码。

The way this should work as far as I can tell is it checks to see if the list "bar" is empty (0) or consists of a singleton (1) via x.occupants where x is a defined item within the list bar and may have the characteristic of occupants. So foo gets called, moves through the list and then returns all items that pass the check condition which is x.occupant.

In a language like Java, you'd build a class called "x" where 'x' objects are then assigned to an array or similar. X would have a Field called "occupants" and each index would be checked with the x.occupants method which would return the number that is assigned to occupant. If that method returned greater than 1 (We assume an int here as a partial occupant would be odd.) the foo method (being called on the array or similar in question.) would then return an array or similar as defined in the foo method for this container array or what have you. The elements of the returned array would be the 'x' objects in the first array thingie that fit the criteria of "Greater than 1".

Python has built-in methods via list comprehension to deal with this in a much more succinct and vastly simplified way. Rather than implementing two full classes and several methods, I write that one line of code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文