0

There is a question with exactly the same title in stackoverflow but the problem is not what I want to ask. I was solving a leetcode problem and found there is a quite interesting difference between the list comprehension and for loop. Please compare the following two approaches.

Approach 1

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

Approach 2

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

Approach 1 hangs while Approach 2 does not and produces a correct result. The reason I think is that:
1) Approach 1 adds element to set1 for each member of set1. Thus, the for loop never ends because set1 list is ever growing.
2) Approach 2 updates set1 after all the elements in set1 are processed. Am I on the right track in understanding the difference between two approaches? Also, can I consider [ s + [n] for s in set1] as a list resulted from the following pseudo code?

tmp = []
for s in set1:
   tmp += [s + [n]]
1
  • 1
    Yes. That's pretty much it. Commented Mar 6, 2019 at 1:40

2 Answers 2

1

The problem is that you're modifying the list you're iterating on in the for s in set1 loop. This could be avoided by using copy() to ensure that you iterating on a separate instance of the list : for s in set1.copy(). you could also constrain the length of the loop: for s in set1[:len(set1)]

Sign up to request clarification or add additional context in comments.

Comments

1

I think your two approaches are not equal.

The approach two is "extend set1 after compute the list". So the equivalent to approach 2 should like below:

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

Why you approach 1 hang? It's not hang, it's looping forever, because you extend your list while traverse it.

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

Every time you get next element of set1, your set1 get longer.

It is really a bad idea to change the element while traverse it. Don't do that. Creating a middle variable like your pseudo code is more safe and clear.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.