#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    9
    Rep Power
    0

    Problem with default argument value in functions


    text from python v2.7.5 documentation:>

    Important warning: The default argument 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. For example, the following function accumulates the arguments passed to it on subsequent calls:
    [CODE]
    def f(a, L=[]):
    L.append(a)
    return L

    print f(1)
    print f(2)
    print f(3)

    [\CODE]

    This will print

    [1]
    [1, 2]
    [1, 2, 3]
    If you donít want the default to be shared between subsequent calls, you can write the function like this instead:

    [CODE]
    def f(a, L=None):
    if L is None:
    L = []
    L.append(a)
    return L

    [\CODE]

    i didn't get the second part...
    As they say default value is evaluated only once and since lists are mutable....in the second part after one iteration, since L is not None now, it will surpass if statement and a will be appended onto L of last iteration......but this is not happening......why???
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,837
    Rep Power
    480
    The function starts fresh using the original default values.
    Code:
    def f(a, L=None, M=[]):
        if L is None:
            L = []
        L.append(a)
        M.append(a)
        return L
    
    print(f.__defaults__) # shows  (None, [])
    
    print(f('hi world'))  # shows ['hi world']
    
    print(f.__defaults__) # shows (None, ['hi world'])
    You can make a callable continue from where it left off using the yield statement.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    Iran
    Posts
    149
    Rep Power
    139
    Originally Posted by datus
    ....in the second part after one iteration, since L is not None now, it will surpass if statement and a will be appended onto L of last iteration......but this is not happening......why???
    This is because you don't provide the list as an effective parameter, therefore python according to the default value defined at function prototype consider it to be None, no matter how many time you call the function, p_list is valid only within the scope of your function, it is a formal parameter which is affected by an effective parameter (if you provide any). Compare the following

    python Code:
    def myFun(p_newVal, p_list = None):
        if p_list is None:
            p_list = []
     
        p_list.append(p_newVal)
     
        return p_list
     
    retVal = myFun(10)
    retVal = myFun(11)
    retVal = myFun(12)
    print retVal
    The output is
    Code:
    $ python -tt myscript.py
    [12]
    $
    Now almost the same code, but this time you provide your list as effective parameter

    python Code:
    def myFun(p_newVal, p_list = None):
        if p_list is None:
            p_list = []
     
        p_list.append(p_newVal)
     
        return p_list
     
    mylist = []
    retVal = myFun(10, mylist)
    retVal = myFun(11, mylist)
    retVal = myFun(12, mylist)
    print retVal
    And this time the output is
    Code:
    $ python -tt myscript.py
    [10, 11, 12]
    $
    Regards,
    Dariyoosh
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    9
    Rep Power
    0
    thanks Dariyoosh!!!

    you made me catch the point!!!

    now what i got is:>

    In the first example:

    When python gets to the function definition, a list is created -

    this will be used as a default argument for L

    The function is called without an argument for L

    The default list is used

    1 is appended to the list

    When the function is called again, the default list already contains 1

    2 gets appended to the default list
    ...


    In the second example:

    None is used as a default argument

    The function is called without an argument for L - the default gets used

    Since L is indeed None, a new list is created and assigned to L

    1 is appended to that list

    On the next call, None is again used as a default value

    Since L is None, a new empty list is created

    2 is appended to that list
    ...

IMN logo majestic logo threadwatch logo seochat tools logo