Python列表的理解和条件的顺序

时间:2014-10-01 13:32:41

标签: python-2.7

以下列表理解之间是否存在差异:

1

f = [(x,y) for x in a if x > 0 for y in b]

print f

2

f = [(x,y) for x in a for y in b if x > 0]

print f

1 个答案:

答案 0 :(得分:0)

简短回答不,稍微回答一下。

当您写下类似内容时:

f = [(x,y) for x in range(a) if x > 0 for y in range(b)]

然后你可以把它重写为以下我将称之为p1:

for x in range(a):
    if (x > 0):
        for y in range(b):
            f.append((x, y))
print f

当你写下以下内容时:

f = [(x,y) for x in range(a) for y in range(b) if x > 0]

然后您可以将其重写为以下内容,我将其称为p2:

for x in range(a):
    for y in range(b):
        if (x > 0):
            f.append((x,y ))
print f

我这样重写了它们,因为它更容易理解。

我应该注意,我不建议在for循环中使用for循环,因为它越来越难以处理代码,只有在必要时才使用它。

在p1中,它将检查是否x>在运行下一个for循环之前为0。

这样做的好处是,如果x> 0,您甚至不必完成剩余的流程。 0因此节省了时间。它不会检查y的新值,因为你告诉它它是不必要的。

p2必须在决定是否x>之前运行两个for循环。这不如p1有效。

关键区别在于p1应该比p2更有效,因为它可以节省时间。最后他们都给出了相同的结果。

p1中发生的事情称为短路。这不像电子产品那样糟糕。短路只意味着你做一个布尔检查,看看是否有必要评估一个陈述的其余部分。

我们假设我们必须使用布尔值x和y。 x设置为false,而y设置为true。我们可以评估以下声明:

if x && y:
    print 'Hello World!'

&&(和)运算符首先检查x是真还是假。如果x为假,则没有理由继续作为&&运算符要求两个语句都为真。我们在这里短路,因此不评估y,也不运行打印功能。

让我们再次使用相同的布尔值。我们可以评估以下声明:

if y || x:
    print 'Hello World!'

由于y被评估为真,因此不会评估x。 ||运算符只需要一个真正的布尔语句,因为y为真,所以它不会评估x。

这有一个很好的属性,我们可以隐藏'操作员右侧的陈述。如果正确的语句可能导致程序崩溃,例如sqrt(-1),其中-1是用户输入,那就太棒了。

如果您想了解有关短路评估的更多信息,那么您可以在Wikipedia.上阅读更多内容