Python confusing function reference

Can anyone explain to me why the two functions below a and b are behaving differently. Function a changes names locally and b changes the actual object.

Where can I find the correct documentation for this behavior?

def a(names):
    names = ['Fred', 'George', 'Bill']

def b(names):
    names.append('Bill')

first_names = ['Fred', 'George']

print "before calling any function",first_names
a(first_names)
print "after calling a",first_names
b(first_names)
print "after calling b",first_names

Output:

before calling any function ['Fred', 'George']
after calling a ['Fred', 'George']
after calling b ['Fred', 'George', 'Bill']

Best answer

Function a creates a new, local variable names and assigns list ['Fred', 'George', 'Bill'] to it. So this is now a different variable from the global first_names, as you already found out.

You can read about modifying a list inside a function here.

One way to make function a behave the same as function b is to make the function a modifier:

def a(names):
    names += ['Bill']

Or you could make a pure function:

def c(names):
    new_list = names + ['Bill']
    return new_list

And call it:

first_names = c(first_names)
print first_names
# ['Fred', 'George', 'Bill']

A pure function means it doesn’t change the state of the program, i.e. it doesn’t have any side effects, like changing global variables.