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中的单行循环矢量化。这是真的?这是否意味着他们可以更快地迭代而不是多行循环?
答案 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层。
当然,理解与其他任何事情都有局限性。如果您想对列表/集的每个元素执行更大的操作集,那么正常循环可能更合适。