El concepto de evaluación "perezosa" normalmente viene con lenguajes funcionales, pero en esos no se podía reasignar dos valores diferentes al mismo identificador, por lo tanto, ni siquiera se podía reproducir su ejemplo.
El punto no se trata en absoluto la pereza - es que el uso de un identificador se garantiza que sea idéntica a conseguir una referencia al mismo valor que el identificador hace referencia, y reasignar un identificador, un desnuda el nombre, con un valor diferente, garantiza que el identificador haga referencia a un valor diferente de ellos. La referencia al primer valor (objeto) no se pierde.
Considere un ejemplo similar donde la reasignación a un nombre simple no está en juego, sino más bien cualquier otro tipo de mutación (para un objeto mutable, por supuesto, los números y las cadenas son inmutables), incluida una asignación a algo demás que un nombre al descubierto:
>>> a = [1]
>>> list = [a]
>>> print list
[[1]]
>>> a[:] = [2]
>>> print list
[[2]]
Puesto que no hay a - ...
que vuelve a asignar el nombre al descubierto a
, sino más bien una a[:] = ...
que reasigna a
's contenidos, es trivialmente fácil de hacer Python como 'perezosa' como desee (y de hecho tomaría tan ¡Me esfuerzo por hacerlo "ansioso"! -) ... si la pereza frente al entusiasmo tenía algo que ver con cualquiera de estos casos (que no ;-).
Simplemente tenga en cuenta la semántica perfectamente simple de "asignar a un nombre simple" (frente a la asignación a cualquier otra cosa, que puede ser variadamente ajustado y controlado utilizando sus propios tipos de forma adecuada), y la ilusión óptica de "perezoso vs ansioso "podría desvanecerse ;-)
Esto no es lo que he entendido que es la evaluación perezosa. Diría que es más como esto: queremos encontrar los primeros 30 números positivos cuyo cuadrado es divisible por 3. Con un lenguaje entusiasta, o codifica el rendimiento - 'while (list.length <30) if (i * i % 3 == 0) list + = i ++; 'o expresividad (pero tirando enormes listas innecesarias a lo largo del camino) -' list1 = rango 0..10000; para i en list1 si i * i% 3 == 0 list2.add i; list2.trim (30) '.Con perezoso escribes algo más como este último, pero obtienes el rendimiento del anterior. Daniel Tao [lo explica brillantemente] (http://danieltao.com/lazy.js/). –
Una forma lenta podría verse así: 'range(). Filter (var donde var * var% 3 == 0) .take (30)' - está escrito muy expresivamente, pero el código no se ejecuta de manera imperativa. Se ejecuta: 'range' genera 1.' Filter' - falla porque '1 * 1% 3! = 0'. Entonces 'range' genera 2.' Filter' falla. Entonces 'range' genera 3.' Filter' pasa porque '3 * 3% 3 == 0'. 'Take' lo colas como una respuesta. Después de 'tomar' ha tomado 30, el algoritmo se detiene. Solo usa la cantidad de memoria que necesita, pero también es un código altamente legible (y paralelo). –