2

I'm fairly new at Python and i cannot wrap my head around the results im getting Using the code below:

def func(a,b=set()):
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

print(func([1,1,2,2,3,4]))
print(func([1,1,2,2,3,4]))

I was getting output:

[1,2,3,4]
[]

I put "print(b)" above "res=list()" and got output:

set()
[1,2,3,4]
{1,2,3,4}
[]

What is going on? Shouldn't "b" be set to "set()" when i call the function? Im using Python 3.6

Mar Ok
  • 23
  • 3
  • 2
    Have a read of the important warning herehttps://docs.python.org/3/tutorial/controlflow.html#default-argument-values – match Jan 28 '18 at 09:56

3 Answers3

4

Have a look at the documentation for default parameters:

The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes.

When you define a function with a default parameter, the default value is only evaluated when the definition is first executed by the interpreter (the actual def statement). This is usually not a problem, except for when a mutable default value is used. That is to say, one that can be modified in place.

In your case, when you modify b in your function the first time you call it, it keeps that value the next time around. To avoid this, you can do like so:

def func(a,b=None):
    if b is None:
        b = set()
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

Now b will always have the default value you want.

stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
2

In python functions are objects and arguments are evaluated and executed once. this is a nice explanation : http://effbot.org/zone/default-values.htm

in your example, it could be "fixed" by doing:

def func(a,b=None):
    if b is None:
        b = set()
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res
corroleaus
  • 41
  • 2
1

In First function call b is empty See here

enter image description here

In second function call b is already fill with element enter image description here

So this condition not run if i not in b and return empty list

Try this

def func(a):
    res=list()
    b=set()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

print(func([1,1,2,2,3,4]))
print(func([1,1,2,2,3,4]))

Output

[1, 2, 3, 4]

[1, 2, 3, 4]

Community
  • 1
  • 1
Artier
  • 1,648
  • 2
  • 8
  • 22