La función cambia los valores de la lista y los valores no variables en Python

Tomemos un código simple:

y = [1,2,3]

def plusOne(y):
    for x in range(len(y)):
        y[x] += 1
    return y

print plusOne(y), y


a = 2

def plusOne2(a):
    a += 1
    return a

print plusOne2(a), a

Los valores de 'y' cambian pero el valor 'a' se mantiene igual. Ya aprendí que es porque uno es mutable y el otro no. Pero, ¿cómo cambiar el código para que la función no cambie la lista?

Por ejemplo, para hacer algo así (en pseudocódigo para simplificar):

a = [1,2,3,...,n]

function doSomething(x):
    do stuff with x
    return x

b = doSomething(a)

if someOperation(a) > someOperation(b):
    do stuff

EDIT: lo siento, pero tengootra pregunta en listas anidadas. Ver este codigo

def change(y):
    yN = y[:]
    for i in range(len(yN)):
        if yN[i][0] == 1:
            yN[i][0] = 0
        else:
            yN[i][0] = 1
    return yN

data1 = [[1],[1],[0],[0]]
data2 = change(data1)

Aquí no funciona. ¿Por qué? De nuevo: ¿cómo evitar este problema? Entiendo por qué no funciona: yN = y [:] copia los valores de y a yN, pero los valores también son listas, por lo que la operación debería duplicarse para cada lista en la lista. ¿Cómo hacer esta operación con listas anidadas?

Respuestas a la pregunta(7)

Su respuesta a la pregunta