Search code examples
pythonpowerset

Python Power set , can't figure out my error


My code will crash and run forever:

def subsets(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    results = [[]]
    for num in nums:
        for result in results:
            results.extend([result + [num]])
    return results 

While I googled, and find similar solution:

def subsets(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    results = [[]]
    for num in nums:
        results.extend([result + [num] for result in results])
    return results

What's the difference here?


Solution

  • The critical part is this:

    for result in results:
        results.extend([result + [num]])
    

    Here, you are iterating over the results list. An iterator is always something living, that does not finish until you actually reached the end. For lists, you can simply imagine this as a pointer that starts at the first element, and then keeps going to the next until it reaches the end.

    Except that in your case, you are adding an element (since [result + [num]] is a one-element list) to the results list on every iteration. So as the iterator keeps going forward, you keep adding one element to the end making sure the iterator can never reach the end.

    As a general rule, you should never modify the collection you are currently iterating. So in this case, you shouldn’t modify results while you are iterating the same thing.

    And that’s exactly what the following line in that other solution avoids:

    results.extend([result + [num] for result in results])
    

    This uses a list comprehension and is essentially equivalent to this:

    tmp = []
    for result in results:
        tmp.append(result + [num])
    results.extend(tmp)
    

    As you can see, results is not modified while iterating over it. The tmp list is first created, and then once that’s done, the results list is modified by extending it by the whole tmp list.