Python 列表([]) 和 [] [英] Python list([]) and []

查看:20
本文介绍了Python 列表([]) 和 []的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

from cs1graphics import *从数学导入 sqrt数量链接 = 50休息长度 = 20.0总分离度 = 630.0弹性常数 = 0.005重力常数 = 0.110ε = 0.001def combine(A,B,C=(0,0)):返回 (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])距离 = sqrt(dX*dX+dY*dY)如果距离>休息长度:拉伸 = 距离 - 静止长度forceFactor = 拉伸 * 弹性常数别的:力因子 = 0return (forceFactor * dX, forceFactor * dY) #返回一个元组def drawChain(chainData, chainPath, theCanvas):对于范围内的 k(len(chainData)):chainPath.setPoint(Point(chainData[k][0],chainData[k][1]),k)theCanvas.refresh() #刷新画布chain = [] #chain在这里对于范围内的 k(numLinks + 1):X = totalSeparation * k/numLinkschain.append((X,0.0))纸 = 画布(totalSeparation,totalSeparation)paper.setAutoRefresh(False)曲线 = 路径()对于链中的 p:curve.addPoint(Point(p[0], p[1]))paper.add(曲线)图形计数器 = 100somethingMoved = 真当某物移动时:somethingMoved = 假oldChain = list(chain) #oldChain 这里对于范围内的 k(1, numLinks):重力=(0,重力常数)leftForce = calcForce(oldChain[k], oldChain[k-1])rightForce = calcForce(oldChain[k], oldChain[k+1])调整=结合(重力,左力,右力)如果 abs(adjust[0]) >epsilon 或 abs(adjust[1]) >厄普西隆:somethingMoved = 真链[k] = 结合(旧链[k],调整)图形计数器 -= 1如果 graphicsCounter == 0:drawChain(链,曲线,纸)图形计数器 = 100曲线.setBorderWidth(2)drawChain(链,曲线,纸)

有人告诉我list([]) == [].那么为什么这段代码在做
oldChain = list(chain) 而不是 oldChain = chain

这是同样的事情,所以无论哪种方式都没有关系?

解决方案

list(chain) 返回一个chain的浅拷贝,相当于chain[:].

如果你想要一个列表的浅拷贝,那么使用 list(),它有时也用于从迭代器中获取所有值.

y = list(x)y = x 的区别:

<小时>

浅拷贝:

<预><代码>>>>x = [1,2,3]>>>y = x #this 只是创建一个对同一个列表对象的新引用>>>y 是 x真的>>>y.append(4) # 附加到 y,也会影响 x>>>x,y([1, 2, 3, 4], [1, 2, 3, 4]) #两者都变了#浅拷贝>>>x = [1,2,3]>>>y = list(x) #y 是 x 的浅拷贝>>>x 是 y错误的>>>y.append(4) #附加到y不会影响x,反之亦然>>>x,y([1, 2, 3], [1, 2, 3, 4]) #x 还是一样

<小时>

深拷贝:

请注意,如果 x 包含可变对象,那么仅 list()[:] 是不够的:

<预><代码>>>>x = [[1,2],[3,4]]>>>y = list(x) #外部列表不同>>>x 是 y错误的

但是内部对象仍然是对 x 中对象的引用:

<预><代码>>>>x[0] 是 y[0],x[1] 是 y[1](真,真)>>>y[0].append('foo') #修改一个内部列表>>>x,y #changes 可以在两个列表中看到([[1, 2, 'foo'], [3, 4]], [[1, 2, 'foo'], [3, 4]])

由于外部列表不同,修改 x 不会影响 y,反之亦然

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

为了处理这个使用copy.deepcopy.

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)

I was told that list([]) == []. So why is this code doing
oldChain = list(chain) instead of oldChain = chain

it's the same thing so it does not matter either way to do it?

解决方案

list(chain) returns a shallow copy of chain, it is equivalent to chain[:].

If you want a shallow copy of the list then use list(), it also used sometimes to get all the values from an iterator.

Difference between y = list(x) and y = x:


Shallow copy:

>>> 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 


Deepcopy:

Note that if x contains mutable objects then just list() or [:] are not enough:

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

But inner objects are still references to the objects in 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]])

As the outer lists are different then modifying x will not affect y and vice-versa

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

To handle this use copy.deepcopy.

这篇关于Python 列表([]) 和 []的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆