单行& Python中的多行循环和矢量化

时间:2012-12-03 22:57:50

标签: python loops

Python中的单行循环只能用于构建列表吗? (即列表推导),还是可以用于更一般的计算?

例如,我知道Python中的列表推导(〜单行循环),例如

my_list = [ 2*i for i in range(10)]

也可以使用多行循环构建:

my_list = []
for i in range(10):
    my_list.append(2*i)

但是我们总是可以将一般的多行循环转换为单行循环吗?

例如,假设我们有以下多行for循环:

my_array = np.ones(10*10)

for x in range(10):
     my_array[x,:] = 0

我们可以将它转换成单行循环吗?更一般地说:

Q1。这两种形式在功能上是否相同? (即他们支持同一组操作/操作)

Q2。我想我之前已经读过Python中的单行循环矢量化。这是真的?这是否意味着他们可以更快地迭代而不是多行循环?

2 个答案:

答案 0 :(得分:5)

  

但是我们能否总是将Python中的一般多行循环转换为单行循环?

简短的回答是否定的。

列表推导适用于投影(映射)和/或过滤。

例如,如果你有这样的代码:

result = []
for x in seq:
    if bar(x):
        result.append(foo(x))

然后,正如您所指出的那样,它可以从重写为列表理解中受益:

result = [foo(x) for f in seq if bar(x)]

但是,对于不适合此投影或过滤模式的操作,列表推导通常不太好。

例如,如果你需要改变元素但不需要结果,那么列表理解就不合适了。以下代码作为列表推导写入是不方便的(假设两个方法都返回None):

for x in seq:
    x.foo()    # Modify x
    x.bar()    # Modify x again

理解中不允许进行某些操作。例如,如果满足条件,则提前退出循环:

for x in seq:
    if x.foo():
        break
    else:
        x.bar()

答案 1 :(得分:2)

我要指出的一件事是,它不仅仅是列表,你可以使用理解来创建集合甚至字典。

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

此外,列表理解 通常比使用append多次(比如你的例子)更快,因为理解是由底层C代码完成的,而不是append,它有额外的Python层。

当然,理解与其他任何事情都有局限性。如果您想对列表/集的每个元素执行更大的操作集,那么正常循环可能更合适。