2.6 运算符和操作对象
运算符和操作对象是计算机编程中必不可少的组成元素,所有计算都涉及运算符和操作对象,本节将介绍Python中的运算符和操作对象。
2.6.1 什么是运算符和操作对象
运算符是一些特殊符号的集合,前面学习的加(+)、减(-)、乘(*)、除(/)、地板除(//)、取模(%)等都是运算符。操作对象是由运算符连接起来的对象。加、减、乘、除4种运算符是我们从小学就开始接触的,不过在计算机语言中,乘除的写法和之前的写法不一样,这个要记住。读者可以快速回忆一下,在计算机中的乘除是怎么样的,自己去做一个纵向比对,看看计算机的乘除和未接触计算机之前的乘除的差异,借此加深自己的记忆。
Python支持以下7种运算符:
(1)算术运算符。
(2)比较(关系)运算符。
(3)赋值运算符。
(4)逻辑运算符。
(5)位运算符。
(6)成员运算符。
(7)身份运算符。
接下来分别进行介绍。
2.6.2 算术运算符
表2-1为算术运算符的描述和实例。假设变量a为10,变量b为5。
表2-1 算术运算符
下面进行实战。在交互模式下做如下练习:
>>> a = 10 >>> b = 5 >>> print(a + b) 15 >>> print(a - b) 5 >>> print(a * b) 50 >>> print(a / b) 2.0 >>> print(a ** b) 100000 >>> print(9 // 2) 4 >>> print(9.0 // 2.0) 4.0
此处的加、减、乘、除、取模、地板除前面都已经做过详细介绍,较好理解。但是幂运算的计算形式,与在数学中学习的乘方运算的形式不一样,数学中是a2这样的形式,幂运算是a**2的形式。有没有更好的方式让人更容易记住这个符号呢?
有一个很好的例子,相信读者经常会被问到你的操作系统是32位还是64位的,或在安装某个软件时,经常会被问到是否支持64位操作系统等。
为什么会出现32位和64位的操作系统,并且现在读者都趋向于安装64位的软件?
先看交互模式下的两个输入:
>>> 2 ** 32 / 1024 / 1024 / 1024 4.0 >>> 2 ** 64 / 1024 / 1024 / 1024 17179869184.0
第一个输入,2**32是2的32次方,这是32位操作系统最大支持内存的字节数,除以第一个1024是转换为KB,1KB=1024B,除以第二个1024是转换为MB,1MB=1024KB,除以第三个1024是转换为GB,1GB=1024MB。这个结果告诉我们,32位的操作系统最大只能支持4GB的内存,现在手机都是4GB内存的标配了,计算机4GB的内存怎么够用呢?所以读者都趋向于选择64位操作系统。
2.6.3 比较运算符
表2-2为比较运算符的描述和实例。以下假设变量a为10、变量b为20。所有比较运算符返回1表示真,返回0表示假,与特殊的变量True和False等价。注意大写的变量名。
表2-2 比较运算符
下面进行实战。
>>> a = 10 >>> b = 20 >>> a == b False >>> a != b True >>> a > b False >>> a < b True >>> a >= b False >>> a <= b True >>> a + 10 >= b True >>> a + 10 > b False >>> a<=b-10 True >>> a < b - 10 False >>> a == b - 10 True
小智:小萌,注意到比较运算的特色了吗?
小萌:比较运算只返回True和False两个值。
小智:对的,能看出比较运算符两边的值和比较的结果有什么特色吗,特别是对于==、<、>、<=、>=这5个比较运算符的结果?
小萌:让我仔细观察观察,对于这些比较运算,只要左边和右边的操作数满足操作符的条件,结果就是True,不满足就是False。
小智:你理解的没错,其实可以通俗地理解为,比较结构符合大家的心理预期,结果就是True,不符合就是False。比如上面的例子中a<b,即10<20,符合大家的预期,就返回True;对于a==b,即10==20,大家一眼就能看出这两者不相等,就返回False。
提示
在一些地方,会用1代表True、0代表False,这是正确也是合理的表示方式。大家可以理解为开和关,就像我们在物理中所学的电源的打开和关闭一样。后面会有更多地方用1和0代表True和False。
另外,在Python 2中,有时会看到<>符号。和!=一样,<>也表示不等于,在Python 3中已去除该符号。
2.6.4 赋值运算符
表2-3为赋值运算符的描述和实例。假设变量a为10,变量b为20。
表2-3 赋值运算符
下面进行实战。
>>> a = 10 >>> b = 20 >>> c = 0 >>> c = a + b >>> print(c) 30 >>> c += 10 >>> print(c) 40 >>> c -= a >>> print(c) 30 >>> c *= a >>> print(c) 300 >>> c /= a >>> print(c) 30.0 >>> c %= a >>> print(c) 0.0 >>> c = a ** 5 >>> print(c) 100000 >>> c //= b >>> print(b) 20 >>> print(c) 5000
2.6.5 位运算符
位运算符是把数字看作二进制进行计算的。表2-4为Python中位运算符的描述和实例。假设变量a为60,变量b为13。
表2-4 位运算符
下面进行实战。
>>> a = 60 >>> b = 13 >>> c = 0 >>> c = a & b >>> print(c) 12 >>> c = a | b >>> print(c) 61 >>> c = a ^ b >>> print(c) 49 >>> c = ~a >>> print(c) -61 >>> c = a << 2 >>> print(c) 240 >>> c = a >> 2 >>> print(c) 15
2.6.6 逻辑运算符
Python语言支持逻辑运算符,表2-5为逻辑运算符的描述和实例,假设变量a为10,变量b为20。
表2-5 逻辑运算符
下面进行实战。
>>> a = 10 >>> b = 20 >>> a and b 20 >>> a or b 10 >>> not a False >>> not b False >>> not -1 False >>> not False True >>> not True False
2.6.7 成员运算符
除之前介绍的运算符外,Python还支持成员运算符,表2-6为成员运算符的描述和实例。
表2-6 成员运算符
下面进行实战。
>>> a = 10 >>> b = 5 >>> list = [1, 2, 3, 4, 5] >>> print(a in list) False >>> print(a not in list) True >>> print(b in list) True >>> print(b not in list) False
你可能会疑惑list是什么,list是一个集合,此处不做具体讲解,后面章节会有详细介绍。
2.6.8 身份运算符
身份运算符用于比较两个对象的存储单元,表2-7为身份运算符的描述和实例。
表2-7 身份运算符
下面进行实战。
>>> a = 10 >>> b = 10 >>> print(a is b) True >>> print(a is not b) False >>> b = 20 >>> print(a is b) False >>> print(a is not b) True
提示
后面已对变量b重新赋值,因而输出结果与前面不太一致。
2.6.9 运算符的优先级
表2-8列出了从最高到最低优先级的所有运算符。
表2-8 运算符的优先级
当一个表达式中出现多个操作符时,求值的顺序依赖于优先级规则。Python中运算符的优先级规则遵守数学操作符的传统规则。
小智:“小萌,你还记得以前所学的数学里面操作符的优先级规则是怎样的吗?”
小萌:“还记得,就是有括号先算括号里的,无论是括号里还是括号外的,都是先乘除、后加减。”
在Python中有更多操作运算符,可以使用缩略词PEMDAS帮助记忆部分规则。
(1)括号(Parentheses,P)拥有最高优先级,可以强制表达式按照需要的顺序求值,括号中的表达式会优先执行,也可以利用括号使得表达式更加易读。
例如,对于一个表达式,想要执行完加减后再做乘除运算,在交互模式下输入如下:
>>> a = 20 >>> b = 15 >>> c = 10 >>> d = 5 >>> e = 0 >>> e = (a - b) * c / d >>> print('(a-b)*c/d=', e) (a-b)*c/d= 10.0
顺利达到了我们想要的结果,如果不加括号会怎样呢?
>>> e = a – b * c / d >>> print('a-b*c/d=', e) a-b*c/d= -10.0
结果与前面完全不同了,这里根据先乘除后加减进行运算。如果表达式比较长,加上括号就可以使得表达式更易读。
>>> e = a + b + c – c * d >>> print('a+b+c-c*d=', e) a+b+c-c*d= -5
以上输入没有加括号,表达式本身没有问题,但看起来不太直观。如果进行如下输入:
>>> e = (a + b + c) - (c * d) >>> print('(a+b+c)-(c*d)=', e) (a+b+c)-(c*d)= -5
这样看起来就非常直观。运算结果还是一样的,但我们一看就能明白该表达式的执行顺序是怎样的。
(2)乘方(Exponentiation,E)操作拥有次高的优先级,例如:
>>> 2 ** 1 + 2 4 >>> 2 ** (1 + 2) 8 >>> 2 ** 2 * 3 12 >>> 2 * 2 ** 3 16 >>> 2 ** (2 * 3) 64
以上结果解释:2的一次方为2,加2后结果为4;1加2等于3,2的3次方结果为8;2的2次方为4,4乘以3等于12;2的3次方为8,2乘以8等于16;2乘以3等于6,2的6次方为64。
(3)乘法(Multiplication,M)和除法(Division,D)优先级相同,并且高于有相同优先级的加法(Addition,A)和减法(Subtraction,S),例如:
>>> a + b * c - d 165 >>> a * b / c + d 35.0
(4)优先级相同的操作按照自左向右的顺序求值(除了乘方外),例如:
>>> a + b – c + d 30 >>> a + b – c - d 20
其他运算符的优先级在实际使用时可以自行尝试判断。若通过观察判断不了,则可以在交互模式下通过实验进行判断。