程序员入伙书——赋值语句

赋值语句,就是把一个值搁到一个变量里的过程。

完成这个过程很简单,一个“=”足矣。打开Python,随意输入类似这样的语句:

>>> radius = 10
>>> pi = 3.1415926535897932
>>> circumference = radius * pi * 2
>>> circumference
62.83185307179586
>>> 

看看,几条赋值语句就把半径等于10的圆的周长求出来了,是不是很容易?这些语句当然可以简单地写成10 * 3.1415926535897932 * 2,这里演示的是思考的过程。

初学编程的人,容易在两件事上不习惯,我这里单列出来:

一、“=”不是“相等”的意思,而是“把等号右边的值算出来,放到等号左边的变量里去”。
二、赋值完成后,等号左边变量原有的值就被覆盖了,消失了,找不回来了。

这些要点,以前举例时说过或者暗示过,这次隆重重申一下。为了体会第一点,试试这段代码(以前的例子里挺常见的):

>>> total = 0
>>> total = total + 3
>>> total
3
>>> total = total + 4
>>> total
7
>>> 

像total = total + 4这种代码,现在在我眼里,是再正常不过的东东,但刚学编程的时代,是每次一瞧心里都咯噔一下的,因为把“等式”两边各减去total,即得到0 = 4。这怎么可能?!现在看顺眼了,因为我现在明白这句话就是三个步骤:把total的值读出来放到一个运算器里,在这个运算器里加4,把运算器的结果放回到total里去。

像这种在原变量上执行的简单加减乘除操作,Python支持下面这种写法,看起来直观,也省了很多敲键盘的事儿:

>>> total = 0
>>> total += 3
>>> total
3
>>> total += 4
>>> total
7
>>> 

 

关于刚才提到的第二点(赋值是不可逆的覆盖),我想用举个例子来说明。考虑两个变量值的对换,即:如果a = 3,b = 4,那么对换后a = 4,b = 3。

初学者大概很容易像下面的程序这样写,结果沮丧地发现,a和b的值被弄得相等了:

>>> a = 3
>>> b = 4
>>> a = b
>>> b = a
>>> a
4
>>> b
4
>>>

为什么呢?因为执行到a = b的时候,b的值(4)就跑到a里来了,a被完全地、不可逆地覆盖。当执行下一句b = a时,a的值早已不是旧模样(3),相当于b把自己的值又写进自己一回。最后两个变量都等于4。

所以,这么一个简单的操作,在计算机的世界里,得这样考虑:先把a的值放到别处暂存一下,然后把b的值放到a里来,再把a的那个副本放进b里去,这样就完成对换工作了。按照这个思路得到代码如下:

>>> a = 3
>>> b = 4
>>> c = a
>>> a = b
>>> b = c
>>> a
4
>>> b
3
>>>

哦耶!成功了!

我学编程的时代,还和同学们交流过这样一个智力题:如果不使用中间变量,能完成两个变量的对换么?

考虑一分钟,再看下面的答案,亲自在Python里试一试,真的能干活:

>>> a = 3
>>> b = 4
>>> a = a + b
>>> b = a - b
>>> a = a - b
>>> a
4
>>> b
3
>>> 

这段程序精确地表达了刚才提到的两个要点:一、等号不是等式,而是赋值。二、赋值是不可逆的覆盖。

但是,请一定注意:这段程序绝对不是正确的数据对换方法!它太难懂!它会出错!它慢!计算机也不在乎这么一个临时变量的内存空间!写这样的程序除了炫技,没有任何意义。在有经验的程序员眼里,这是极烂的代码!原因是:第一、这样的代码不好懂,再过半年,连你自己看了都会怔一下。第二、因为机器存储数字的局限性,加减运算是会偷偷改变数字的精度的。第三、计算机里的数字有上限,不能表达到数学上的无穷大,如果a + b超过了计算机能表达的范围(行话叫“溢出”),直接就悲剧了。而开创一个临时变量做搬家运动的方法,第一、不会有数学风险,第二、在计算机里,执行搬家指令比运算指令更省时间,这句话对人脑同样有效。

以下这些是Python特色的赋值。Python可以批量地对多个变量赋值,办法是用逗号隔开多个变量,放在一对小括号里。称为“组元”(Tuple),一个组元可以接受个数相等的另一个组元的集体赋值,集体赋值采取“捉对厮杀”规则,相同位置的值放到相同位置的变量里去,像下面的例子这样,原本需要一个临时变量的数据对换操作,用组元一下子就搞定了:

>>> a = 3
>>> b = 4
>>> (a, b) = (b, a)
>>> a
4
>>> b
3
>>> 

不用担心“假如a的值被b冲掉了,还怎么赋给b”的问题,组元赋值是成批的而不是分步的,就是说,“=”右边括号里的所有值全部准备好之后,再写进左边的各变量里去,即:

一、准备“=”右边的内容,取出b和a的值放到括号里,即(4, 3)。
二、把右边的内容赋给左边的变量,即把(4, 3)分发给(a, b),得到a = 4,b = 3。

Python语言还有一种特色赋值方法,就是连等。这个语句很直观,我就不用说明了,直接看例子:

>>> a = b = c = 3.14
>>> a
3.14
>>> b
3.14
>>> c
3.14
>>> 
评论关闭