Default value for optional parameters unexpected behaviour?

Discussion in 'Python' started by Marc Aymerich, Jun 26, 2011.

  1. Hi,
    I'm trying to define a function that has an optional parameter which
    should be an empty list whenever it isn't given. However, it takes as
    value the same value as the last time the function was executed. What
    is the reason of this behaviour? How does python deal with default
    values (i.e. when are they assigned/created)?

    Thanks :)

    >>> def a(foo=[]):

    .... foo.append(1)
    .... print foo
    ....
    >>> a()

    [1]
    >>> a()

    [1, 1]
    >>> a()

    [1, 1, 1]
    >>> a()

    [1, 1, 1, 1]
    >>> a()

    [1, 1, 1, 1, 1]
    >>> a()

    [1, 1, 1, 1, 1, 1]
    Marc Aymerich, Jun 26, 2011
    #1
    1. Advertising

  2. Excerpts from Marc Aymerich's message of Sun Jun 26 14:28:30 -0400 2011:
    > Hi,
    > I'm trying to define a function that has an optional parameter which
    > should be an empty list whenever it isn't given. However, it takes as
    > value the same value as the last time the function was executed. What
    > is the reason of this behaviour? How does python deal with default
    > values (i.e. when are they assigned/created)?
    >
    > Thanks :)
    >


    Really common mistake, I made it myself too. When Python evaluates the
    function, it sees the default parameter of `foo' as the new object you
    create with []. It keeps that object around. The proper idiom instead of

    > >>> def a(foo=[]):

    > ... foo.append(1)
    > ... print foo
    > ...


    is

    def a(foo=None):
    if foo is None:
    foo = []
    foo.append(1)
    print foo
    --
    Corey Richardson
    "Those who deny freedom to others, deserve it not for themselves"
    -- Abraham Lincoln

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.17 (GNU/Linux)

    iQEcBAEBCAAGBQJOB3wgAAoJEAFAbo/KNFvpOcYH/jrb1pD5t88KfyMDB4Uu/Rwc
    okXbnkppQaWv5yD6zGImVpQT07e8geHqfbWhVuu8EZFr4zwsXQPcLu8n4hTsltH6
    KFpzdWEJnqdr1DkU26dJhKBGdLpaXil6WxqWA2dERPCvEYNetQnkjpxhLJMuSDq8
    osfx9mMhLiNmM5AAcqi+8+lm7xhSmLTHBEgIT9GTnrpdbxEWOtDRGXdiEb0FQB6A
    2yc1aMGSWJgcvBPKRCgU336pIe5/miN+e9UDiCHpc3RnKaodThS5QVJQCDI99BW4
    czbWMPzQLaVMLDnYzpjJ7lJ5BibuB0SVrrXuLCzC7YpMa2/HpKXbp11k7AlOP5E=
    =m0c1
    -----END PGP SIGNATURE-----
    Corey Richardson, Jun 26, 2011
    #2
    1. Advertising

  3. On Sun, Jun 26, 2011 at 11:58 PM, Marc Aymerich <> wrote:
    > Hi,
    > I'm trying to define a function that has an optional parameter which
    > should be an empty list whenever it isn't given. However, it takes as
    > value the same value as the last time the function was executed. What
    > is the reason of this behaviour? How does python deal with default
    > values (i.e. when are they assigned/created)?


    This has been discussed before in this list, quite a few times
    http://mail.python.org/pipermail/python-list/2010-March/1239044.html

    A solution is to accept default value as None assign to [] by checking
    for None inside the function

    def f(a=None):
    if a is None: a = []



    --
    Regards
    Shashank Singh
    http://rationalpie.wordpress.com
    Shashank Singh, Jun 26, 2011
    #3
  4. Marc Aymerich

    Noah Hall Guest

    On Sun, Jun 26, 2011 at 7:28 PM, Marc Aymerich <> wrote:
    > Hi,
    > I'm trying to define a function that has an optional parameter which
    > should be an empty list whenever it isn't given. However, it takes as
    > value the same value as the last time the function was executed. What
    > is the reason of this behaviour? How does python deal with default
    > values (i.e. when are they assigned/created)?
    >
    > Thanks :)
    >
    >>>> def a(foo=[]):

    > ...  foo.append(1)
    > ...  print foo
    > ...
    >>>> a()

    > [1]
    >>>> a()

    > [1, 1]
    >>>> a()

    > [1, 1, 1]
    >>>> a()

    > [1, 1, 1, 1]
    >>>> a()

    > [1, 1, 1, 1, 1]
    >>>> a()

    > [1, 1, 1, 1, 1, 1]


    Your problem arises because lists are mutable. Because foo (by
    default, initially) points to a given list, every time the function is
    called, it uses the same list that foo was first pointed to, if the
    default argument value is taken.
    The way to fix this is to instead do -

    def a(foo=None):
    if foo is None:
    foo = []
    Noah Hall, Jun 26, 2011
    #4
  5. Marc Aymerich

    Terry Reedy Guest

    On 6/26/2011 2:28 PM, Marc Aymerich wrote:
    > Hi,
    > I'm trying to define a function that has an optional parameter which
    > should be an empty list whenever it isn't given. However, it takes as
    > value the same value as the last time the function was executed. What
    > is the reason of this behaviour? How does python deal with default
    > values (i.e. when are they assigned/created)?


    Our fine Language Reference. Compound Statements chapter, Function
    definitions section, says in bold type: "Default parameter values are
    evaluated when the function definition is executed. ". I presume the
    tutorial says this somewhere too. Read both, along with the first 5
    chanpter of the Library reference.

    If you want code executed when you call the function, put it in the body
    that is executed when you call the function

    def f(lst = None):
    if lst is None:
    lst = []
    ...

    --
    Terry Jan Reedy
    Terry Reedy, Jun 26, 2011
    #5
  6. On Sun, Jun 26, 2011 at 11:28 AM, Marc Aymerich <> wrote:
    > Hi,
    > I'm trying to define a function that has an optional parameter which
    > should be an empty list whenever it isn't given. However, it takes as
    > value the same value as the last time the function was executed. What
    > is the reason of this behaviour? How does python deal with default
    > values (i.e. when are they assigned/created)?
    >
    > Thanks :)
    >


    So the thing about Python is that you don't actually declare
    functions. You create them. def is an executable statement that
    creates a function object. Default arguments are part of the function
    object, so they get evaluated when the function is created.

    >>> foo

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'foo' is not defined
    >>> def foo(a = []) :

    .... a.append(1)
    ....
    >>> foo.func_defaults

    ([],)
    >>> foo()
    >>> foo.func_defaults

    ([1],)
    >>>
    Benjamin Kaplan, Jun 26, 2011
    #6
  7. Excerpts from Thomas L. Shinnick's message of Sun Jun 26 14:53:21 -0400 2011:
    > See reference manual section 7.6 "Function definitions" under the
    > discussion subtitle "Default parameter values are evaluated when the
    > function definition is executed. "
    > http://docs.python.org/reference/compound_stmts.html#function-definitions
    >
    > Yes, this is discussed in many places and many times, but why isn't
    > it in the Python FAQ? Amazing, yes?
    >


    Well, to be fair, I don't think most people actually read the FAQ.
    The FAQ does say:

    "Default arguments can be used to determine values once, at compile
    time instead of at run time. This can only be done for functions or
    objects which will not be changed during program execution..."

    And he did modify the list during program execution. However this
    isn't exactly forthright if you aren't looking for it / know what
    you're reading. I don't think it should be spilled out in detail but
    maybe a "there are some tricks involved with mutable default
    arguments (for example a list). Refer to the language reference
    (LINK) for more details" would be useful.

    But I'm not really certain that would make much of a difference.
    I'll Cc this to .
    --
    Corey Richardson
    "Those who deny freedom to others, deserve it not for themselves"
    -- Abraham Lincoln

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.17 (GNU/Linux)

    iQEcBAEBCAAGBQJOB4dRAAoJEAFAbo/KNFvpOBkH/02mQjm7OTmIr+pRz4vWUYhW
    dFPzS5OJdAyVPvF4NSAGrDCBD7D5QkYTOvow+jz5zZ/b9veXAArb//XAKC6EjzdO
    GuzFoOCKo28YMQ611tLL02ZI/7moB69Ftc3K/zD4uSFOgEok0coOwrQyOti1hsgw
    er7W72SLsoRSeFqoreoGy8yXTOFdRT8SROgAoocVAgmyfGWgjVu2+cQoP5cONps2
    Clwcgf0cXfcFsfyCYbyk6ZOmBxH+jDRrrvGPwIH3BnJt/8ECLfKRJNsquw81D9ti
    E5+yf7lkmZO+zRpEGzwmn0AEQoDah4U78pLuxOMlPvGZaympCAH+ubgfTHG0BYE=
    =W9Uf
    -----END PGP SIGNATURE-----
    Corey Richardson, Jun 26, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Do
    Replies:
    1
    Views:
    67,179
    Kevin Spencer
    Oct 16, 2003
  2. ruca

    Optional and have default value

    ruca, Apr 12, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    423
    Marina
    Apr 12, 2004
  3. Replies:
    5
    Views:
    289
  4. wyo
    Replies:
    5
    Views:
    110
    scripts.contact
    Apr 28, 2007
  5. Giacomo Alzetta
    Replies:
    10
    Views:
    240
    Giacomo Alzetta
    Nov 22, 2012
Loading...

Share This Page