Cambiaré el nombre de las variables para reducir la confusión. n -> nf o nmain . x -> xf o xmain :
def f(nf, xf):
nf = 2
xf.append(4)
print 'In f():', nf, xf
def main():
nmain = 1
xmain = [0,1,2,3]
print 'Before:', nmain, xmain
f(nmain, xmain)
print 'After: ', nmain, xmain
main()
Cuando llama a la función f , el tiempo de ejecución de Python hace una copia de xmain y la asigna a xf , y de manera similar asigna una copia de nmain a nf .
En el caso de n , el valor que se copia es 1.
En el caso de x, el valor que se copia no es la lista literal [0, 1, 2, 3] . Es una referencia a esa lista. xf y xmain apuntan a la misma lista, por lo que cuando modifica xf también modifica xmain .
Sin embargo, si escribieras algo como:
xf = ["foo", "bar"]
xf.append(4)
encontrará que xmain no ha cambiado. Esto se debe a que, en la línea xf = ["foo", "bar"] , debe cambiar xf para que apunte a una nueva lista. Cualquier cambio que realice en esta nueva lista no tendrá efectos en la lista a la que xmain todavía apunta.
Espero que ayude. :-)