Assignment never copies. After backup = week, both names point to the same list, so week.append(4) changes what backup shows too.
To get an independent list, copy it: week.copy(), list(week) or week[:]. Dictionaries have .copy() as well.
Those are shallow copies: the outer container is new, but anything nested inside is still shared. A dictionary holding a list needs copy.deepcopy(...) if you want to change the inner list separately.
[[0] * 3] * 3 looks like a 3 by 3 grid, but it repeats one inner list three times, so changing one row changes all of them. Build each row separately: [[0] * 3 for _ in range(3)].
Functions receive the object itself, so a function that calls .append on a list argument changes the caller's list. Numbers and text can't change in place, which is why this only bites with lists, dictionaries and sets.