列表理解与for循环之间的区别

时间:2019-03-06 01:35:42

标签: python for-loop list-comprehension

stackoverflow中有一个标题完全相同的问题,但问题不是我要问的。我在求解leetcode problem时发现列表理解和for循环之间有一个非常有趣的区别。请比较以下两种方法。

方法1

set1 = [[]]
num = [1,2,3]
for n in num:
    for s in set1:
        set1 += [ s + [n] ]
print(set1)

方法2

set1 = [[]]
num = [1,2,3]
for n in num:
    set1 += [ s + [n] for s in set1]
print(set1)

Approach 1挂起,而Approach 2未挂起并产生正确的结果。我认为的原因是:
1)Approach 1为set1的每个成员向set1添加元素。因此,for循环永远不会结束,因为set1列表不断增长。
2)Approach 2在set1中的所有元素 之后更新set1。在理解两种方法之间的区别时,我是否走上了正确的轨道?另外,我可以将[ s + [n] for s in set1]视为以下伪代码生成的列表吗?

tmp = []
for s in set1:
   tmp += [s + [n]]

2 个答案:

答案 0 :(得分:1)

问题在于您正在修改要在for s in set1循环中迭代的列表。可以通过使用copy()来确保您在列表的单独实例上进行迭代来避免:for s in set1.copy()。您还可以限制循环的长度:for s in set1[:len(set1)]

答案 1 :(得分:1)

我认为您的两种方法不尽相同。

方法二是“在计算列表之后扩展set1”。因此,方法2的等效项应如下所示:

set1 = [[]]
num = [1,2,3]
for n in num:
    tmp = []
    for s in set1:
        tmp += [ s + [n] ]
    set1 += tmp
print(set1)

为什么您要挂1次?它不是挂起的,而是永远循环的,因为在遍历列表时会扩展列表。

    for s in set1:
        set1 += [ s + [n] ]

每次获得set1的下一个元素时,您的set1就会变长。

在遍历元素时更改元素确实是一个坏主意。不要那样做创建像您的伪代码这样的中间变量更安全,更清楚。