Lista de Python () y

from cs1graphics import * from math import sqrt numLinks = 50 restingLength = 20.0 totalSeparation = 630.0 elasticityConstant = 0.005 gravityConstant = 0.110 epsilon = 0.001 def combine(A,B,C=(0,0)): return (A[0] + B[0] + C[0], A[1] + B[1] + C[1]) def calcForce(A,B): dX = (B[0] - A[0]) dY = (B[1] - A[1]) distance = sqrt(dX*dX+dY*dY) if distance > restingLength: stretch = distance - restingLength forceFactor = stretch * elasticityConstant else: forceFactor = 0 return (forceFactor * dX, forceFactor * dY) #return a tuple def drawChain(chainData, chainPath, theCanvas): for k in range(len(chainData)): chainPath.setPoint(Point(chainData[k][0], chainData[k][1]),k) theCanvas.refresh() #refresh canvas chain = [] #chain here for k in range(numLinks + 1): X = totalSeparation * k / numLinks chain.append( (X,0.0) ) paper = Canvas(totalSeparation, totalSeparation) paper.setAutoRefresh(False) curve = Path() for p in chain: curve.addPoint(Point(p[0], p[1])) paper.add(curve) graphicsCounter = 100 somethingMoved = True while somethingMoved: somethingMoved = False oldChain = list(chain) #oldChain here for k in range(1, numLinks): gravForce = (0, gravityConstant) leftForce = calcForce(oldChain[k], oldChain[k-1]) rightForce = calcForce(oldChain[k], oldChain[k+1]) adjust = combine(gravForce, leftForce, rightForce) if abs(adjust[0]) > epsilon or abs(adjust[1]) > epsilon: somethingMoved = True chain[k] = combine(oldChain[k], adjust) graphicsCounter -= 1 if graphicsCounter == 0: drawChain(chain, curve, paper) graphicsCounter = 100 curve.setBorderWidth(2) drawChain(chain, curve, paper) 

Me dijeron que la list([]) == [] . Entonces, ¿por qué está haciendo este código
oldChain = list(chain) lugar de oldChain = chain

¿Es lo mismo por lo que no importa de ninguna manera hacerlo?

list(chain) devuelve una copia superficial de la chain , es equivalente a la chain[:] .

Si desea una copia superficial de la lista, use list() , que también se usa a veces para obtener todos los valores de un iterador.

Diferencia entre y = list(x) y y = x :


Copia superficial:

 >>> x = [1,2,3] >>> y = x #this simply creates a new referece to the same list object >>> y is x True >>> y.append(4) # appending to y, will affect x as well >>> x,y ([1, 2, 3, 4], [1, 2, 3, 4]) #both are changed #shallow copy >>> x = [1,2,3] >>> y = list(x) #y is a shallow copy of x >>> x is y False >>> y.append(4) #appending to y won't affect x and vice-versa >>> x,y ([1, 2, 3], [1, 2, 3, 4]) #x is still same 

Copia profunda:

Tenga en cuenta que si x contiene objetos mutables, solo la list() o [:] no son suficientes:

 >>> x = [[1,2],[3,4]] >>> y = list(x) #outer list is different >>> x is y False 

Pero los objetos internos siguen siendo referencias a los objetos en x:

 >>> x[0] is y[0], x[1] is y[1] (True, True) >>> y[0].append('foo') #modify an inner list >>> x,y #changes can be seen in both lists ([[1, 2, 'foo'], [3, 4]], [[1, 2, 'foo'], [3, 4]]) 

Como las listas externas son diferentes, la modificación de x no afectará a y, y viceversa

 >>> x.append('bar') >>> x,y ([[1, 2, 'foo'], [3, 4], 'bar'], [[1, 2, 'foo'], [3, 4]]) 

Para manejar esto use copy.deepcopy .

Es cierto que la list([]) es funcionalmente equivalente a [] , creando una nueva lista vacía.

Pero x = list(y) no es lo mismo que x = y . Los formadores hacen una copia superficial y esta última crea una nueva referencia a la lista existente.

Tenga en cuenta que la list([]) es ineficiente: crea una nueva lista vacía (haciendo [] ), luego la copia, resultando con otra lista vacía (haciendo list(...) ), luego desasigna el original, sin referencia lista

 oldchain = list(chain) 

oldchain apunta a una nueva lista que no es una cadena (no es el mismo objeto) pero tiene el mismo contenido.
* Como otras respuestas han mencionado, esto hace que oldchain sea una “copia superficial” de la cadena.

 oldchain = chain 

oldchain solo apunta a la cadena, ambos apuntan al mismo objeto

Sin embargo, tenga en cuenta que oldchain = [] y oldchain = list() son funcionalmente iguales ya que ambos están creando una lista vacía. Se vuelve diferente cuando otras referencias (es decir, la chain ) están involucradas.

Si ayuda, aquí está la explicación tomada directamente de la página 189 del libro (Progtwigción Orientada a Objetos en Python), justo debajo de la presentación del código dado:

“Una sutileza importante en nuestro enfoque se ve en la línea 52. Esta línea hace que oldChain sea una copia de la cadena. Tenga en cuenta que se trata de una semántica bastante diferente del comando oldChain = chain, que simplemente haría que el identificador oldChain referencia sea el mismo subyacente La necesidad de esta copia es la siguiente. El bucle interno se usa para volver a calcular la posición de cada punto interior de la cadena, uno por uno. Queremos hacer todos esos cálculos basados ​​en un estado coherente de la cadena. Si no hubiéramos hecho una copia, nos encontraríamos con el siguiente problema. El ajuste al segundo punto de la cadena depende de las posiciones del primer y tercer punto. Supongamos que debíamos hacer ese ajuste y luego continuar. El siguiente El paso sería calcular el ajuste al tercer punto, que depende de las posiciones del segundo y cuarto punto. Pero ahora habría una discrepancia entre la posición anterior del segundo punto y su posición actualizada. Queremos usar el Posición anterior del segundo punto por coherencia. Por esta razón, calculamos todas las fuerzas basadas en la copia de la cadena antigua “.