难点和错误

Python接受一些省事的赋值手法,比如:

x = 3; y = 4    # 一行做了两个赋值

x,y = y,x

执行后x的值4,y的值为3,相当于将x和y的值做了对调。

x,y = y,x一行就对调了x和y的值,等于替代了三条语句:

    temp=x; x=y; y=temp

可见python对懒人的赋值手法相当宽容。

python也接受连续赋值,比如:

x = y ='cheer'   # 赋值后,x和y的值都为字符串'cheer'

x = 5            # 改变了x的值
print(x,y)       # 运行结果显示x的值为5,y的值仍为'cheer'

来猜猜下面的这段程序运行结果是啥?

x=y=[]
x.append(3)
print(x,y)

按照上一段程序的运行逻辑,x添加了个元素,应该变成[3],而y则继续保持空列表[]的状态。然而就被检验真理的唯一标准-实践毫不犹豫滴打了一巴掌:在电脑上运行这段程序的结果是x和y的值都变成了[3]!

x=3; y=3与x=y=3一样,赋数值和字符串确实没区别。但当数值是数列、集合、字典或其他更复杂的数据类型时就有区别了,x=[]; y=[]与x=y=[]是不同的。

Python变量赋值前无需指定数据类型,它的数据类型跟着所赋的值走,赋的值是列表变量就是列表类型,所以x和y是列表类型。如果说x=3好像把3放进一个标记着x的箱子里,那么x=[]或x=[1,2,3]的x则是一个位置索引,指明一个位置处有一排箱子或有个位置将会放一排箱子。

x=[]; y=[]的x和y是两个位置索引,指示不同的位置,只不过恰好这两个位置都没放箱子。

x=[]; y=[]之后x.append(3)是说位置索引x指示的那个位置放一个装3的箱子,而这个行为跟y指示的那个位置没关系,因为x和y本来就指示不同的位置。

x=y=[]的x和y是同一个位置索引的不同叫法,实际上它俩标识的位置是相同的。

x=y=[]之后x.append(3)说明在x指示的那个位置处放了一个装3的箱子。x和y指示同一个位置,所以位置索引y标示的位置处也多了个装3的箱子。

来看下面这段程序:

dxdy = [(0,0.33), (0.33,0.33), (0.75,1), (0.875,0.875),(0.875,0.875), (1,0.75), (0.33,0.33), (0.33,0)]
numSet = set()
for x, y in dxdy:
   numSet.add(x)
numList = list(numSet)
numList.sort()
xd,yd = 300, 200

xc,yc = xd,yd

xList = []; yList = []
for n in numList:
   for (x,y) in ((xc-n*xd,yc-n*yd),(xc+n*xd,yc+n*yd)):
      xList.append(x)
yList.append(y)

print(sorted(xList))
print(sorted(yList))
 

运行结果:

[0, 37.5, 75.0, 201.0, 300, 300, 399.0, 525.0, 562.5, 600]

[0, 25.0, 50.0, 134.0, 200, 200, 266.0, 350.0, 375.0, 400]

如果把标成红色的语句xList = []; yList = []

改成xList = yList = [],则运行结果为

[0, 0, 25.0, 37.5, 50.0, 75.0, 134.0, 200, 200, 201.0, 266.0, 300, 300, 350.0, 375.0, 399.0, 400, 525.0, 562.5, 600]

[0, 0, 25.0, 37.5, 50.0, 75.0, 134.0, 200, 200, 201.0, 266.0, 300, 300, 350.0, 375.0, 399.0, 400, 525.0, 562.5, 600]

后记:写这个帖子是因为最近在做“生成pdf“的系列视频,有一个用贝塞尔曲线生成的图形长这样:

为了方便理解就加了点代码想把标尺和坐标加上去:

结果却是这样:

找来找去找不到原因,无奈深入观察变量变换打印列表内容时才发现是当初图省事,把xList = []; yList = []简写成xList = yList = []惹出来的“祸”。