Search code examples
pythonargumentsgeneratordefault-value

python generator argument are not initialized as default value


Maybe this is a very easy question to someone, I can't understand what this happened.

I try to solve problems using python generator. However, sometime generator seems not to work that I expected.

The code below is the very simple python generator. It takes integer n and set visited as its arguments. visited should be initialized set() when the function is called.

def simple_gen(n, visited=set()): 
    for i in range(0, n):
        if i not in visited:
            yield i
            visited.update([i])

a = simple_gen(10)
b = simple_gen(10)
print(f"a: {list(a)}")
print(f"b: {list(b)}")

But, when the code is executed, the output is like below. generator a generator value like that I expected, but b doesn't. b doesn't generator any value, it is just empty value.

arguement visited always initialized to empty set as default value. but it doesn't look like initializing.

a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b: []

I don't understand why this happened. Are there anyone know this, please let me know.

I always thanks for your help.


Solution

  • Python's default parameters are stored in the function object. This means they're only created once when the function is defined, they are not initialised every time the function is called.

    As a result, if you modify a mutable parameter, that modification will remain between calls.

    And that's exactly what you're doing here: you have a mutable default parameter, you add stuff to it on the first call, and on the second call visited starts as {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. That's why you don't normally use mutable default parameters in Python, it's very error prone and somewhat tricky to debug.

    Create your visited as a normal local variable, I don't see any reason why it'd even be a parameter.