1

In the code below, I've been wondering how we could tell if a parameter, b, is given.

The problem is that the third call of func does not retain [5] in a newly created list but rather some pointer in the start that b is pointing to. I'm guessing this is defined before in the program stack entering func call itself, so the calling and returning of func would not change b...?

Any insight is appreciated.

def func(a, b=[]):

    b.append([a])
    print(b)
    return b

func(3)
func(4, [])
func(5)
Alec
  • 8,529
  • 8
  • 37
  • 63
meesinlid
  • 661
  • 1
  • 5
  • 12
  • 1
    `func(a, b=None): b = b if b is not None else []` see e.g. https://docs.python-guide.org/writing/gotchas/ – hiro protagonist Apr 21 '19 at 06:34
  • 3
    Related reading: ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – TrebledJ Apr 21 '19 at 06:41
  • 1
    Possible duplicate of [Why does using `arg=None` fix Python's mutable default argument issue?](https://stackoverflow.com/questions/10676729/why-does-using-arg-none-fix-pythons-mutable-default-argument-issue) – smci Apr 21 '19 at 08:36
  • @hiroprotagonist perfect – meesinlid Apr 21 '19 at 21:54
  • Thank you all for the pointers – meesinlid Apr 21 '19 at 21:54

2 Answers2

2

The best way is to assign the default value of b to something arbitrary (usually None) then check if b is defined that way:

def func(a, b=None):
    if b is None:
        b = []

    b.append([a])
    print(b)
    return b

func(3)
func(4, [])
func(5)
Alec
  • 8,529
  • 8
  • 37
  • 63
  • Hi, Thank you for the idea. I'm doing more research into why and how this is part of the design .. – meesinlid Apr 21 '19 at 07:38
  • 1
    It has to do with the fact that functions are objects in python. They are only defined once. http://effbot.org/zone/default-values.htm – Alec Apr 21 '19 at 07:44
1

You can define b to a default value, e.g. b=None, and then pick either the value of b if given, or pick an empty list.

def func(a, b=None):

    lst = b or []
    lst.append([a])
    print(lst)
    return lst

func(3)
#[[3]]
func(4, [])
#[[4]]
func(5)
#[[5]]
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40