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


Answers:


83

当前的答案是好的,但不会谈论它们只是我们习惯的某种模式的语法糖

让我们从一个示例开始,假设我们有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
  • 如果condition(x)返回任何False-y值(False,None,空字符串,空列表等),则当前迭代将被跳过(认为continue)。如果函数返回非False-y值,则当前值将其返回到最终的结果数组(并通过上面的转换步骤)。

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

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


奖金

(略显Python风格,但出于完整性考虑将其放在此处)

上面的示例可以写成:

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

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

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

我通常把第一件事称为表达;如果只是x*x,通常可能只是在那里,而不是square(x)。与之相比,当我看到该表达式罐装成lambda(例如[x**2 for x in range(5)]vs.)时,情况就更加痛苦了map(lambda x: x**2, range(5))
尼克T

26

这是一个列表理解

foo将是bar包含属性占用者> 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>]

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

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

2
此答案严格比接受的答案好,但未标记为答案,因为它在4分钟后出现。
user1717828 15/10/27

1

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

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

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


请参阅我在答案中添加的示例
John La Rooy

0

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


0

由于问题的编程部分已由其他人完全回答,因此很高兴知道其与数学的关系(集合论)。实际上,这是Set builder符号Python实现

通过规格公理定义一个集合:

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

英语翻译:是,其成员选自一组,所以的一个子集(B⊂A),其中特征(一个或多个)由函数指定小号成立:S(x) == True

使用列表理解定义B

B = [如果S(x),则A中x为x

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.