Это происходит потому, что компиляция в Python выполняется путем выполнения описательного кода.
Если один сказал
def f(x = {}):
....
было бы довольно ясно, что вы каждый раз хотели новый массив.
Но что, если я скажу:
list_of_all = {}
def create(stuff, x = list_of_all):
...
Здесь я бы предположил, что хочу создать материал в различных списках и иметь единый глобальный охват, когда я не указываю список.
Но как компилятор будет догадываться об этом? Так зачем пытаться? Мы могли бы положиться на то, было ли это названо или нет, и это могло бы иногда помочь, но на самом деле это было бы просто предположение. В то же время, есть веская причина, чтобы не пытаться - последовательность.
Как таковой, Python просто выполняет код. Переменной list_of_all уже присвоен объект, поэтому этот объект передается по ссылке в код, который по умолчанию равен x, так же, как при вызове любой функции будет получена ссылка на локальный объект, названный здесь.
Если бы мы хотели отличить неназванный случай от именованного, это привело бы к тому, что при компиляции код выполнял присваивание существенно другим способом, чем он выполняется во время выполнения. Поэтому мы не делаем особого случая.