stackoverflow中有一个标题完全相同的问题,但问题不是我要问的。我在求解leetcode problem时发现列表理解和for循环之间有一个非常有趣的区别。请比较以下两种方法。
set1 = [[]]
num = [1,2,3]
for n in num:
for s in set1:
set1 += [ s + [n] ]
print(set1)
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]]
答案 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
就会变长。
在遍历元素时更改元素确实是一个坏主意。不要那样做创建像您的伪代码这样的中间变量更安全,更清楚。