2

Can someone explain me why, when I call this function multiple times, L is never set to empty by default? But instead the result of any following call is L appended to all results of preceding calls?

The function separates the data into blocks of 7 days, starting with the last date ([::-1]), calculates the mean of each 7 days and appends the result as a value to a list. Ignores incomplete blocks

The default value for data is a list of dates in ordinal format.

def separate(data = [i for i in w][::-1],L = []):
    print("separate has been called, data is %s and L is %s" % (data, L))

    if len(data)<7:
        return L

    total = 0
    dates = 0

    for value in data[:7]:
        if w[value] != "None":
            total += float(w[value])
            dates += 1
    L.append(total / dates)

    return separate(data[7:], L)
Anon
  • 23
  • 2
  • I thought it has something to do with append changing the list value directly, but the definition of L should be only in the function's scope, right? – Anon Jul 27 '14 at 13:07
  • What is `w`? Is something changing it? – Mark Reed Jul 27 '14 at 13:08
  • w is a variable pointing to a section in a config file which holds dates. The default data value is a list comprehension of all of these data reversed. But the value of data remains constant, it's the L that seems to keep it's value. – Anon Jul 27 '14 at 13:13

1 Answers1

2

Taken from the the documentation:

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.

[...]

If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
Stefan
  • 2,460
  • 1
  • 17
  • 33
  • Thanks, now I feel a bit stupid. Probably the fact that one of the default values remained constant was what irritated me. – Anon Jul 27 '14 at 13:20
  • How should I implement this in a recursive function? Checking for L to be [] would be impossible since L is supposed to hold values during the recursion... – Anon Jul 27 '14 at 13:25
  • This example checks if `L` is `None`, which is much easier. And in your example, you supply an actual parameter for `L` so the default value doesn't matter anymore. – Stefan Jul 27 '14 at 13:30
  • Understand. Basically I will have to use this workaround every time I use mutable default values.... In this case, it would probably also work if I used a tuple instead of a list, right? If anyone else is having the same question, this link also helped and explained it in detail: http://effbot.org/zone/default-values.htm – Anon Jul 27 '14 at 13:41