1. 运算符和表达式的应用方式
程序就是对数据进行处理 , 表示数据的值(对象)可以用变量给它们起名字(用变量名引用这些值(对象)) , 对这些变量或值进行处理可使用一些特殊的符号如+、*等进行加法、乘法等运算 , 这些表示不同运算功能的特殊符号称为运算符(operators)。这些运算符操作的变量或值称为"运算数(operands)"。例如:
2+3
3/(5+2)
3*"world"用+、/、*、(、)这些运算符对运算数进行运算的式子就是表达式(expression) , 即表达式是由运算数(值、变量、对象)和运算符构造的。
因为这些表示运算的运算符来自人们熟悉的符号 , 用它们构成的表达式的含义都很清楚。
不同类型的对象支持的运算符是不同的 , 如不能对 2 个 str 字符串类型的变量应 用-、*、/、//等运算 , 也不能对 1 个字符串和 1 个整数进行如-、+、/等运算。例如 , 下面的都是非 法的:
'hi'-1 'Hello'/123 'hi'*'Hello' '15'+2 即使可以对 2 个字符串应用+运算符 , 其含义也不同于 2 个整数的加法运算 , 而实际是对 2 个 字符串进行拼接。同样 , 对 1 个字符串和 1 个整数可以应用乘法运算符* , 其含义是产生一个重复复制的字符串。例如:
>>> s1 = "hello"
>>> s2 = s1+"world"
>>> s3 =3*"world"
>>> print(s2)
helloworld
>>> print(s3)
worldworldworld不同运算符具有不同的优先级和结合性。例如:
3+5/2 #优先级:先乘除后加减
3+5-2 #结合性:从左向右计算"3+5/2"中运算符/优先于+ , “3+5-2”中+和-具有同样的优先级 , 但它们的结合性都是"从左向右" 。因此 , 先计算左边的+ , 再计算右边的-。
2. 运算符种类
Python 有不同功能的各种运算符 , 如进行数学计算的"算术运算符" , 比较2 个运算数大小的"比较运算符" , 进行逻辑运算的"逻辑运算符" ,对二进制位进行操作的"二进制运算符" , 有对变量赋值的"赋值运算符" ,还有一些特殊的运算符。
算术运算符(
arithmetic operators)//表示整数除法 , 而/表示的是浮点除法 ,%用于求2个整数相除的余数。如:
>>> print(15.3/2.5) 6.12 >>> print(15.3//2.5) #转为整数除 , 相当于15//2 6.0 >>> print(15.3%2.5) #15.3除2.5的余数 0.3000000000000007 >>> print(15.3**2.5) #15.3的2.5次方 915.6480546203329 >>>比较运算符(
comparison operators)对两个量进行比较 , 产生的结果是一个表示"真"(
True)或"假"(False)的bool(布尔)类型的值。例如:逻辑运算符(
logical operators)逻辑运算符
and、or、not分别表示逻辑与、逻辑或、逻辑非运算。 在逻辑运算中 ,True、非0或非空对象就是真(True) , 而False、0或空对象就是假(False)。 当一个对象x是真(True、非0值或非空值)时 ,not x就是False, 当x是假(False、0或空值) 时 ,not x就是True(真)。例如:>>> print(not 0) True >>> print(not []) True >>> print(not False) True >>> print(not 2) False >>> print(not [3]) False >>> print(not True) False >>>假设有
2个对象x、y, 当x是真时 ,x or y的结果就是x, 当x是假时 ,x or y的结果就是y。 例如:>>> print(3 or 5) #因为3是真 , 所以3 or 5的结果就是3 3 >>> print(3 or 2) #因为3是真 , 所以3 or 2的结果就是3 3 >>> print(0 or 2) #因为0是假 , 所以0 or 2的结果就是2 2 >>> print(False or True) True >>> print(False or []) [] >>> print({} or 2) #因为{}是假 , {} or 2的结果就是2 2 >>>假设有
2个对象x、y, 当x是真时 ,x and y的结果就是y, 当x是假时 ,x and y的结果就是x。 例如:>>> print(3 and 5) #因为3是真 , 所以3 and 5的结果就是5 5 >>> print(3 and 2) #因为3是真 , 所以3 and 2的结果就是2 2 >>> print(0 and 2) #因为0是假 , 所以0 and 2的结果就是0 0 >>> print(False and True) False >>> print(False and []) False >>> print({} and 2) #因为{}是假 , 所以{} and 2的结果就是{} {} >>>逻辑运算符
and、or、not的含义及其示例如下表所示 :这
3个逻辑运算符具有不同的优先级 ,and优先于or,not优先于and、or。例如 :>>> print(2 or 5 and 3) 2 >>> print( (2 or 5) and 3) #可用圆括号()改变运算符的计算次序 3位运算符(
bit operators)任何量在计算机内存里都是用
1串二进制位表示的。 假如有2个数 ,a = 37和b = 22是用1字节表示的 , 则其内存的二进制位如下所示:a = 0 0 1 0 0 1 0 1 b = 0 0 0 1 0 1 1 0"位运算" : 对运算数的二进制位进行相应的运算。其中 ,
&(位与)、|(位或)、^(异或)是对2个运算数的对应二进制位进行运算 , 而~(取反)、<<(左移位)、>>(右移位)则是对1个运算数的二进制位进行运算。二元位运算符的运算规则如下表所示。
3个二元位运算符的运算规则如下。&(位与)运算:只有p和q都是1时 ,p&q的结果才是1;如果有一个为0, 则结果是0。|(位或)运算:只要p和q有一个是1时 ,p|q的结果就是1;如果p和q都为0, 则结果是0。^(异或)运算:当p和q不同(一个是0, 另一个 是1)时 ,p^q的结果是1, 否则结果是0。
例如 , 对
a、b的&、|、^运算是对它们的对应二进制位进行运算:a & b = 0 0 0 0 0 1 0 0 a | b = 0 0 1 1 0 1 1 1 a ^ b = 0 0 1 1 0 0 1 1下面对
a,b的&、|、^运算的代码>>> a = 37 >>> b = 22 >>> print('a = ','{:08b}'.format(a)) a = 00100101 >>> print('b = ','{:08b}'.format(b)) b = 00010110 >>> print('a&b=','{:08b}'.format(a&b)) a&b= 00000100 >>> print('a|b=','{:08b}'.format(a|b)) a|b= 00110111 >>> print('a^b=','{:08b}'.format(a^b)) a^b= 00110011一元位运算符取反
~、左移<<、右移>>的运算规则如下。~(取反) : 将每个二进制取反(0变成1,1变成0)。例如 , 对x,~x的结果相当于-x-1, 如22的补是-23。<<(左移) : 各二进制位全部左移若干位 , 高位丢弃 , 低位补0。>>(右移) : 各二进制位全部左移若干位 , 无符号数 , 高位补0。
例如 , 对
b的<<、~运算的结果如下:b<<2 = 0 1 0 1 1 0 0 0 ~b = 1 1 1 0 1 0 0 1下面代码输出了对
b的<<、>>运算的二进制表示:>>> print('b = ','{:08b}'.format(b)) b = 00010110 >>> print('b<<2: ','{:08b}'.format(b<<2)) #b的二进制左移2位 , 右边低位补充0 b<<2: 01011000 >>> print('b>>2: ','{:08b}'.format(b>>2)) #b的二进制右移2位 , 左边高位补充0 b>>2: 00000101 >>> print('~b: ','{:08b}'.format(~b)) #~b就是-(b+1) , b=22的补是-23 ~b: -0010111 >>> print(b) 22 >>> print(b<<2) 88 >>> print(b>>2) 5 >>> print(~b) -23 >>>其中的取反运算
~涉及1个数在计算机内部的二进制表示。数字在计算机中是以补码保存的 , 所以Python位运算是作用在补码上的。假如 , 用8位二进制表示 , 正整数1, 其二进制的原码是00000001, 而负整数-1, 其二进制的原码是10000001, 即左边的最高位1表示这是一个负数。除原码外 ,1个数在计算机内部还可以用反码和补码表示。正数的反码与其补码和原码是一样的 , 如1 的反码和补码都是0000001, 而负数的反码除左边最高位外 , 其他位都是原码的取反 , 如-1的反码是11111110, 而补码就是在反码基础上加上1, 即-1的补码是11111111。b=22的原码、反码和补码都是00010110。对b的二进制取反的结果就是11101001, 这个数实际上是-(b+1)的补码。因为-b的二进制原码是10010110, 而-(b+1)的二进制原码是10010111, 其补码就是11101001。但bin()和str的fromat()会将~b的补码表示转换成原码表示 , 因此 , 尽管~b运算产生的二进制是11101001, 但显示的仍是其二进制原码10010111。赋值运算符
赋值运算符
=是给1个对象起1个名字 , 如简单的赋值运算符=的语句"x=3" ,就是给对象3起 了一个变量名x。例如:x = 2 x = x+3在表达式"
x = x+3" 中 , 右边的变量x引用的是原先的对象 , 而左边的变量x引用的是新的结 果对象。简单赋值运算符可以和算术、位运算结合构成复合赋值运算符。例如:
x = 2 x += 3"
x += 3"实际上是"x = x+3"的简写 , 即"将x+3的结果赋值给x" , 也就是说 , 给x+3的结果对象起了一个名字x。变量x现在引用的是一个新的结果对象而不是原来的2, 可以通过输出x的id来验证这一点:>>> x=2 >>> y = x # y和x都是对象2的名字 >>> print(x) 2 >>> print(id(x)) 2866222006544 >>> x**=3 #相当于x = x**3 >>> print(x) 8 >>> print(id(x)) 2866222006736 >>> print(y) 2 >>> print(id(y)) 2866222006544 >>>Python的赋值运算符如下表所示成员运算符(
in,not in)成员运算符
in和not in用于判断一个值(对象)是否在一个容器对象 , 如list、str、tuple对象中 , 这2个运算符返回的结果是True或False。>>> alist = [2,5,7,8] >>> print(3 in alist) False >>> print(5 in alist) True >>> print(3 not in alist) True >>> print(5 not in alist) False身份运算符(
is,is not)身份运算符
is和is not用于判断2个变量(标识符)是不是引用的同一个对象。例如:>>> a = 10 >>> b = 10 >>> print(id(a)) 2866222006800 >>> print(id(b)) 2866222006800 >>> print(a is b) True >>> print(a is not b) False再如:
>>> a = 1000 >>> b = 1000 >>> print(id(a)) 2866223030640 >>> print(id(b)) 2866223030512 >>> print(a is b) False >>> print(a is not b) True这是因为 ,
Python解释器执行时会将小整数驻留在内存中 , 将小整数赋值给多个变量 , 它们实际引用的是同一个对象。而将整数赋值给不同变量 , 这些变量将引用临时创建的不同对象。
3. 运算符的优先级
运算符的优先级
当一个表达式中有多个运算符时 , 这些运算符的计算是有先后次序的 , 即运算符是具有不同的优先级的。例如 ,算术运算符总是"先乘除 , 后加减" , 同样级别的运算符 , 如
+和-则按照“自左往后的次序”计算。例如:3 + 5/2 - 4先做除法"
5/2",然后做加法,即用"3"和"5/2"的结果相加,最后才做减法,即前面加法的结果和4相减。再比如,同样是逻辑运算,
not比and优先级高, 而and比or优先级高。实际上,无须记忆这些运算符的优先级,如果 不清楚不同运算符的优先级,则可以简单地用圆括 号,使其按照希望的意图进行计算。例如:
(3 + 5 ) / (2 - 4)运算符的优先级表
Python运算符的优先级表如下(从上到下 优先级从高变低)。