Even after using python for many years, I still occasionally make this mistake. It is a tough "bug" to track down. Can anyone comment as to why deep-copy is not the norm?
def f(b):
b[0] = 'Goodbye'
a = ['Hello', 'world']
f(a)
It's more efficient to pass function arguments by reference, and it would be fairly baffling if function argument passing did not work like assignment (c.f. C++ copy construction being similar to, but slightly distinct from, assignment).
Less philosophically, everything in Python has pass-by-reference semantics, even ints. The things you might think are passed by value are immutable, so it doesn't really matter whether they are passed by value or by reference. For example:
a = 1
a = a + 1
conceptually creates a new integer object and binds the name a to it, and so does
Simply because it is slow. In the GP's example if a was a much bigger array, copying it over to b would be expensive. On a related note, in C++ for many containers (if not all) in the standard library, copying is the norm; in "The C++ Programming Language" Bjarne Stroustrup warns that it may be slow.