运算符是一种特殊符号,用来表示数据运算、赋值和比较等。运算符将一个或多个操作数连接成可执行语句,用来实现特定功能。Python 中运算符分为如下几种:
(1)、赋值运算符
(2)、算术运算符
(3)、位运算符
(4)、索引运算符
(5)、比较运算符
(6)、逻辑运算符
一、 赋值运算符
Python中“=”是赋值运算符,用于为变量或常量指定值。可将表达式的值赋值给另一个变量。例如:
s1 = 'python' # 将字符串赋值给 s1 变量
flags = True # 为变量 flags 赋值为 True
还可以使用赋值运算符将一个变量的值赋值给另一个变量。例如:
s2 = s1 # 将变量 s1 的值赋值给 s2
Python 的赋值表达式是有值的,赋值表达式的值就是被赋的值,因此还可以进行连续赋值,例如:
x = y = z = 30
这里将 z = 30 表达式的值赋给变量 y,是由于赋值表达式本身也有值,就是被赋的值,因此表达式 z=30 的值是 30,所以 y 也被赋值为 30;以此类推,变量 x 也被赋值为 30。
赋值运算还可以将表达式的值赋给变量,例如:
n1 = 1.23
n2 = n1 + 3 # 将表达式的值赋值给 n2
二、 算术运算符
算术运算符用于执行基本的数学运算,如加、减、乘、除和求余等。
+:加法运算符除可以让数字相加外,还可以作为字符串和序列的连接运算符。示例如下:
x = 1.1
y = 2.2
z = x + y # z 的值是 3.3
s1 = 'hello, ' + 'michael' # 使用 + 连接两个字符串
-:减法运算符可让两个数字相减,还可以作为求负运算符。示例如下:
a = 5.3
b = 3.1
c = a - b # c 的值是 2.2
a = -a # 对 a 求负,此时 a 的值是 -5.3
*:乘法运算符可让两个数字相乘。还可作为字符串或序列的连接运算符,表示将 N 个字符串连接起来。示例如下:
multiply = 5 * 3.14 # 两个数字相乘
print("hello," * 5) # 使用 乘法(*) 将字符串连接起来,输出:hello,hello,hello,hello,hello,
/或//:除法运算符有两个:“/” 是普通除法,除不尽时产生小数;“//”是整除,结果只有商的整数部分,小数部分被丢弃。示例如下:
print(20/6) # 普通除法,输出是:3.3333333333333335
print(20//6) # 整除法,输出是:3
在Python中的除法运算,除数不能为0,否则报 ZeroDivisionError错误。在Python2 中只有一个“/”除法运算符。当两个操作数都是
整数时就是整除,其中有一个是浮点数时,就是非整除运算。
%:求余运算符,求余运算符的两个操作数可以是整数,也可以是小数。求余的结果不一定是整数,它是第一个操作数除以第二个操作数,
得到一个整除的结果后剩下的值就是余数。求余运算的第二个操作数同样不能为0,否则报 ZeroDivisionError错误。示例如下:
print(7%5) # 整数求余,输出是:2
print(7.3%5.1) # 浮点数取余,输出是:2.2
print(-7.3%-5.1) # 浮点数取余,输出是:-2.2
print(7.3%-5.1) # 第二个操作数为负数,输出是:-2.8999999999999995
print(7.3%-2.3) # 第二个操作数为负数,输出是:-1.8999999999999995
print(-7.3%2.3) # 第一个操作数为负数,输出是:1.8999999999999995
print(7%0) # 第二个操作数不能为0,报 ZeroDivisionError错误
在上面的示例中,第四个算式的计算结果为什么不是 -2.9?在Python中求余运算的逻辑是用被除数减去除数的N倍,这里N是 -2,所以得到的结果应该是-2.9。但实际结果是-2.8999999999999995,这是由于浮点数在存储机制导致的。计算机底层的浮点数的存储机制并不是精确保存每一个浮点数的值,浮点数在Python中可能产生精度丢失的问题。比如这里正常的计算结果是-2.9,但实际计算的结果是一个非常接近-2.9的值。
**:乘方运算符。一个方便的运算符,开方运算是乘方运算的逆运算,用“**”可以进行开方运算。示例如下:
print(3**3) # 3的3次方,输出是:27
print(3**(1/2)) # 3的平方根,输出是:1.7320508075688772
print(2**(1/2)) # 2的平方根,输出是:1.4142135623730951
三、 位运算符
位运算常用在图形、图像处理,和创建设备驱动等底层开发中使用。使用位运算可以直接操作数值的原始bit位,在使用自定义的协议进行通信时,使用位运算符对原始数据进行编码和解码了非常有效。
Python中位运算符有下面6个:
&:按位与,需要2个操作数
|:按位或,需要2个操作数
^:按位异或,需要2个操作数
~:按位取反,需1个操作数
<<:左位移运算符,需要2个操作数
>>:右位移运算符,需要2个操作数
示例如下,下面示例中省略了前面24个0:
print(3 & 6) # 00000011 & 00000110 = 00000010,输出:2
print(3 | 6) # 00000011 | 00000110 = 00000111,输出:7
print(~5) # 正数5按位取反,输出是:-6
print(~-5) # 负数5按位取反,输出是:4
正数的原码、反码、补码都是相同的。负数的原码最高位表示符号位,取反码时符号位保持不变,反码加1得到补码。
-5的原码:1000 0000 0000 0000 0000 0000 0000 0101 # 最高位1是符号位
-5的反码:1111 1111 1111 1111 1111 1111 1111 1010 # 反码是原码按位取反,符号位保持不变
-5的补码:1111 1111 1111 1111 1111 1111 1111 1011 # 反码加1得到补码
4的原码:0000 0000 0000 0000 0000 0000 0000 0100 # 对-5的补码按位取反就得到正的二进制数,可直接计算结果,即4的原码
5原码: 0000 0000 0000 0000 0000 0000 0000 0101 # 正数的原码
~5的结果:1111 1111 1111 1111 1111 1111 1111 1010 # 按位取反后最高位符号位是负数,得到的是负二进制数
计算反码: 1000 0000 0000 0000 0000 0000 0000 0101 # 对负二进制数按位取反得到反码,符号位保持不变
得到补码: 1000 0000 0000 0000 0000 0000 0000 0110 # 反码加1得到补码,用补码直接计算结果得 -6
取反小结:
(1)、取反后正数变负数,负数变正数。
(2)、取反后,如果结果为负数,要计算它的补码,根据补码得到最后的十进制结果。
(3)、取反后,如果为正数,则其原码、反码、补码一样,可以直接计算出十进制结果。
(4)、整数的取反运算等于该整数加1后,再对结果取负数运算,用公式总结就是:~x = -(x+1)
print(5^7) # 5异或7,输出是:2
print(5<<2) # 5左移2位,输出是:20
print(-5<<2) # -5左移2位,输出是:-20
print(5>>2) # 5右移2位,输出是:1
print(-5>>2) # -5右移2位,输出是:-2
左移是将操作数的二进制码整体左移指定位数,左移后右边空出来的位以0填充。负数左移时,要先计算其补码,使用补码左移后得到值。右移是将操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位填充。即:如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1。负数右移时,同样要先计算补码,根据补码右移。
位移运算只适合对整型数进行运算。
在进行位移运算时,左移n位相当于乘以2的n次方,右移n位则相当于除以2的n次方(如果不能整除,实际返回的结果是小于除得结果数值的最大整数的)。位移运算不会改变原来的操作数本身。
四、 赋值运算符扩展
赋值运算可以与算术运算符、位移运算符等结合。扩展后的赋值运算符如下:
x += y:相当于 x = x + y
x -= y:相当于 x = x - y
x *= y:相当于 x = x * y
x /= y:相当于 x = x / y
x //= y:相当于 x = x // y
x %= y:相当于 x = x % y
x **= y:相当于 x = x ** y
x &= y:相当于 x = x & y
x |= y:相当于 x = x | y
x ^= y:相当于 x = x ^ y
x <<= y:相当于 x = x << y
x >>= y:相当于 x = x >> y
五、 索引运算符
索引运算符在字符串中经常使用,对应的符号是方括号([]),在方括号中可以使用单个索引值,还可以使用索引范围。在使用索引范围时,还可指定步长。示例如下:
s = "hellopython"
print(s[3:10:2]) # 获取索引3到10的子串,步长为2,输出:lpto
print(s[3:10:3]) # 获取索引3到10的子串,步长为3,输出:lyo
六、比较运算符与 bool 类型
Python中的 bool 类型有两种值:真(True)和 假(False)。在Python中,不等于0的数字(包括负数)都是True,字符或字符串也是True。等于0的数字或者空值为False。此外,True 还可当做数字1进行算术运算,False 可当做数字0进行算术运算。
比较运算符判断两个值(变量、常量、表达式均可)之间的大小,运算结果为真 或 假值。Python中的比较运算符有如下这些:
大于(>)、大于或等于(>=)、小于(<)、小于或等于(<=)、等于(==)、不等于(!=)、判断两个变量引用的对象是否相同(is)、判断两个变量引用的对象是否不相同(is not)。示例如下:
print(5>4) # 输出:True
print(5>4>3) # 实际做的比较是:5>4 and 4>3,输出是:True
print(5>4 and 4>3) # 输出是:True
print(3 ** 3 >= 28) # 3的3次方是否大于或等于28,输出是:False
print(10 >= 10.0) # 10 是否大于或等于 10.0,输出是:True
print(10 == 10.0) # 10 是否等于 10.0,输出是:True
print(True == 1) # True 是否等于数字 1,输出是:True
print(False == 0) # False 是否等于数字 0,输出是:True
print(True + False) # 输出:1
print(False - True) # 输出:-1
等于(==)与 is 的区别,== 只比较两个变量的值,is 是判断两个变量是否引用同一个对象。Python有一个全局(内置)函数可判断变量所引用的对象的内存地址(对象在计算机中存储的门牌号),如果两个对象所在的内存地址相同(计算机同一块内存在任一时刻只能存放一个对象),则说明这两个对象其实是同一个对象。is 就是通过 id() 函数计算两个对象时判断返回的地址是否相同。示例如下:
import time
a = time.gmtime()
b = time.gmtime()
print(a == b) # 输出是:True
print(a is b) # 输出是:False
print(id(a))
print(id(b)) # a 和 b 的内存地址不一样,所以 a is b 是False
七、 逻辑运算符
逻辑运算符用于操作 bool 类型的变量、常量、表达式,逻辑运算的返回值也是 bool 值。逻辑运算符有下面三个:
逻辑与(and):两个操作数都为True,才返回True,否则返回False。
逻辑或(or):两个操作数中有一个为True,就返回True。两个都为False时,才返回False。
逻辑非(not):只要一个操作数,用常于反转条件,当操作数为True,则返回False;当操作数为False,则返回True。
示例如下:
print(not True) # 对True取非运算,输出是:False
print(5>4 and 4>3) # 同时判断两个条件,输出是:True
print("4" > "5" or "b" > "a") # 输出:True
当使用多个逻辑运算组合成复杂的逻辑时,通常要使用圆括号来明确运算顺序,同时也提高程序的可读性。
八、三目运算符
Python中通过 if 语句实现三目运算符功能。语法格式如下:
True_statements if expression else False_statements
首先对逻辑表达式(expression)求值,如果 expression 返回 True,则执行并返回 True_statements 的值;如果 expression 返回 False,则执行并返回 False_statements 的值。示例如下:
x = 8
y = 5
res = "x大于y" if x > y else "x小于y"
print(res) # 输出:x大于y
print("x大于y") if x > y else print('x小于y') # 还可使用这种形式的三目运算符
print("x大于y" if x > y else 'x小于y') # 使用这种形式也是可以的
在True_statements 或 False_statements 中可以放置多条语句。支持的主要方式有两种:
(1)、多条语句以英文逗号隔开:每条语句都会执行,程序返回多条语句的返回值组成的元组。
(2)、多条语句以英文分号隔开:每条语句都会执行,程序只返回第一条语句的返回值。
对于第一种情况,示例如下:
res = print("python"), "x大于y" if x > y else "x小于y" # 执行这条语句输出:python
print(res) # 输出是:(None, 'x大于y')
这里的 True_statements 是 (print("python"), "x大于y"),这两条语句都会执行,程序返回这两条语句的返回值组成的元组。
由于 print() 函数没有返回值,相当于返回值是 None。所以输出是 (None, 'x大于y')。
将上面语句的逗号改为分号,并且修改逗号之后的语句,示例如下:
res = print("python"); z = 10 if x > y else "x小于y" # 执行这条语句输出:python
print(res) # res 只有分号前面语句的返回值,输出:None
print(z) # 分号后面的语句同样被执行了,所以输出:10
另外,三目运算符支持嵌套,通过嵌套三目运算符,可执行更复杂的判断。示例如下:
x = 10
y = 10
print("x大于y" if x > y else ("x小于y" if x < y else "x等于y")) # 输出是:x等于y
九、in运算符
in 运算符可判断某个成员是否在序列中,例如判断某个字符是否在某个字符串中。in 的反义词是 not in,判断的结果都是 bool 型值。
print('on' in 'python.org') # 输出:True
print('on' not in 'python.org') # 输出:False
print('linux' not in 'python.org') # 输出:True
十、 运算符的结合性和优先级
数学运算是从左向右进行的,Python中大部分运算也是从左向右结合的。但是单目运算符、赋值运算符和三目运算符例外,它们是从右向左结合的,也就是从右向左运算的。
乘法和加法是两个可结合的运算符,这两个运算符左右两边的操作数可以互换位置而不影响结果。
此外,运算符有不同的优先级,优先级高的会先计算。按优先级从高到低排列,如下所示:
根据上面的运算符优先级可知,5+5<<2语句的执行顺序是,先执行 5+5 得到结果10,再执行 10<<2 得到40。可以使用圆括号来改变执行顺序,例如 5+(5<<2) 会先执行 5<<2 的结果20与5相加,得到25。
虽然运算符有优先级顺序,但是不要过度依赖运算符的优先级,这样会造成程序可读性变差。通常一个表达式太复杂,可分成几步来完成。另外,当需要明确执行顺序时,尽量使用圆括号来表示。
练习二
# 输入两个整数,并输出这两个整数的整除结果和带小数的除法结果
num_str = input("请输入两个整数,以空格做分隔:")
num_list = num_str.split(" ")
print("%s // %s = %i" % (num_list[0], num_list[1], int(num_list[0]) // int(num_list[1])))
print("%s / %s = %f" % (num_list[0], num_list[1], int(num_list[0]) / int(num_list[1])))
# 从标准输入读取两个整数,并打印三行,第一行是两个整数的和,第二是两个整数的差,第三行是两个整数的乘积
num_str = input("请输入两个整数,以空格做分隔:")
num_list = num_str.split(" ")
num1, num2 = int(num_list[0]), int(num_list[1])
print("%d + %i = %d" % (num1, num2, num1 + num2))
print("%d - %i = %d" % (num1, num2, num1 - num2))
print("%d * %i = %d" % (num1, num2, num1 * num2))
# 输入两个字符串,第一个是字符串,第二个子串,要求判断子串在字符串中出现的次数,如ABCDCDC和CDC,程序输出是2
fist_str = input("请输入第一个字符串:")
second_str = input("请输入第二个子串:")
fist_str_length = len(fist_str)
second_str_length = len(second_str)
n = 0
count = 0
if second_str_length > fist_str_length:
print(count)
elif second_str_length == 1:
print(fist_str.count(second_str))
else:
for _ in range(1, fist_str_length - 1):
if fist_str[n:second_str_length] == second_str:
count += 1
n += 1
second_str_length += 1
else:
n += 1
second_str_length += 1
print(count)
# 输入一个任意整数,输出该整数的十进制、八进制、十六进制、二进制形式的字符串
num = int(input("请输入一个整数:"))
print("十进制形式:%s" % num)
print("八进制形式:%o" % num)
print("十六进制小写形式:%x" % num)
print("十六进制大写形式:%X" % num)
print("二进制形式:%s" % bin(num))
# 修改字符串,要求输入一个字符,修改字符串中指定的位置,例如 6 @ 表示将字符串中6的位置修改为 @ 符号
s = input("请输入一个字符串:")
r = input("请输入修改位置及修改符号,以空格分隔,例如 “6 @”:")
r_list = r.split(" ")
index = int(r_list[0])
s1 = s[0:index] # 如果 index 是 0,则 s[0:0] 是空值
s2 = s[index+1:]
print("修改后的字符串是:", s1 + r_list[1] + s2)