Q:

Why default parameter doesn't work for Python object distinguish

My question is about why default parameter couldn't be used to distinguish different object.
If I define class M1 as:
class M1:
   id = -1
   list1 = []
   def __init__(self,id,list1 = []):
       self.id = id
       self.list1 = list1
   def insertList(self,element):
       self.list1.append(element)

And use it like:
if __name__ == '__main__':
    m1 = M1(1,[])
    m1.insertList("a",[])
    m1.insertList("b",[])
    m2 = M1(2,[])
    print m2.list1

It will return [] as m2.list1 because list1 isn't shared between m1 and m2.
However, if I 'trust' default parameter when I define M1 object, like below:
if __name__ == '__main__':
    m1 = M1(1)
    m1.insertList("a",[])
    m1.insertList("b",[])
    m2 = M1(2)
    print m2.list1

It will return ['a','b'] as m2.list1 and list1 is shared between different objects.
I know class parameter could be defined as static or object member based on whether it's defined in __init__(self), but why default parameter will influence result?

A:

It's to do with lists being mutable, first-class objects (see "Least Astonishment" and the Mutable Default Argument). It will work if you do this:
def __init__(self, id, list1=None):
    if list1 is None:
        self.list1 = []

An assignment inside the function body will refresh the variable.

