04-运算符
1.1 运算符
python是面向对象的编程语言,在Python中的一切都是对象。对象由数据和行为部分组成,而行为主要通过方法来实现,通过一些特殊方法的重写,可以实现运算符重载。运算符也是表现对象行为的一种形式,不同类的对象支持的运算符有所不同,同一种运算符作用于不同的对象时也可能会表现出不同的行为,这正是"多态”的体现。
在Python中,单个常量或变量可以看做最简单的表达式,使用除赋值运算符之外的其他任意运算符和函数调用连接的式子也属与表达式。
除了算术运算符,关系运算符,逻辑运算符以及位运算符等常见运算符之外,python还支持一些特有的运算符,如成员测试运算符,集合运算符,同一性测试运算符等。使用时需注意,Python很多运算符具有不同的含义,作用于不同对象时的含义并不完全相同,非常灵活。常用的python运算符如下表所示。运算符优先级会在本文的1.7节讲述。虽然python运算符有一套严格的优先级规则,但是强烈建议再编写复杂表达式时使用圆括号说明其中的逻辑来提高代码可读性。记住,圆括号是明确和改变表达式运算顺序的利器,在适当的位置使用圆括号可以使得表达式的含义更加明确。
python运算符:
运算符 | 功能说明 |
---|---|
+ | 算数加法,列表,元组,字符串合并和连接,正号 |
- | 算术减法,集合差集,相反数 |
* | 算术减法,序列重复 |
/ | 真除法 |
// | 求整商,如果操作数中有实数,结果为实数形式的整数。 |
% | 求余数,字符串格式化 |
** | 幂运算 |
<,<=,>,>=,==,!= | (值)大小比较,集合的包含关系比较 |
or | 逻辑或 |
and | 逻辑与 |
not | 逻辑非 |
in | 成员测试 |
is | 对象同一性测试,即测试是否为同一个对象或内存地址是否相同 |
,^,&,<<,>>,~ | 位或,位或与,位与,左移位,右移位,位求反 |
&, | ,^ |
@ | 矩阵相乘运算符 |
1.1.1 运算符的概念
运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。例如:2+3,其操作数为2和3,而运算符则是"+"。
1.1.2 运算符的分类
算术运算符,赋值运算符,比较运算符(关系运算符),逻辑运算符,条件运算符(三元运算符)
1.2 算术运算符
(1)+运算除了用于算术加法之外,还可以用于列表,元组,字符串的连接,但不支持不同类型的对象之间的相加或连接。
>>> [1,2,3]+[4,5,6] #连接两个列表
[1, 2, 3, 4, 5, 6]
>>> (1,2,3)+(4,) #连接两个元组
(1, 2, 3, 4)
>>> 'abcd'+'1234' #连接两个字符串
'abcd1234'
>>> 'A'+1 #不支持字符和数字相加,抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must be str, not int
>>> True+3 #python内部把True当作1处理
4
>>> False+3 #把False当做0处理
3
(2)减法运算符,表现形式"-"。
(3)*运算符除了表示算术乘法,还可以用于了列表,元组,还可以用于列表,元组,字符串这几个序列类型与整数的乘法,表示序列元素的重复,生成新的序列对象。字典和集合不支持与整数的相乘,因为其中的元素是不允许重复的。
>>> True*3
3
>>> False*3
0
>>> [1,2,3]*3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> (1,2,3)*3
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> 'abc'*3
'abcabcabc'
(4)运算符/和//在python中分别表示算术除法和算术求整商。
>>> 3/2 #数学意义上的除法
1.5
>>> 15//4 #如果两个操作数都是整数,结果为整数
3
>>> 15.0//4 #如果操作数中有整数,结果为实数形式的整数值
3.0
>>> -15//4 #向下取整
-4
(5)%运算符可以用于整数或实数的求余数运算,还可以用于字符串的格式化,但是并不推荐这种用法。
>>> 789%23 #余数
7
>>> 123.45%3.2 #可以对实数进行余数运算,注意精度问题
1.849999999999996
>>> '%c,%d'%(65,65) #把65分别格式化为字符和整数
'A,65'
>>> '%f,%s'%(65,65) #把65分别格式化为实数和字符串
'65.000000,65'
(5)运算符表示幂乘,等价于内置函数pow()。例如:
>>> 3**2 #3的二次方,等价于pow(3,2)
9
>>> pow(3,2,8) #等价于(3**2)%8
1
>>> 9**0.5 #9的0.5次方,即9的平方根
3.0
>>> (-9)**0.5 #可以计算负数的平方根
(1.8369701987210297e-16+3j)
1.3 赋值运算符
除了上表中的运算符之外,Python还有赋值运算符=和+=,==,-=,* =,**=,/=,//=,|=,^=等大量复合赋值运算符。例如x+=3在语法上等价(注意,在功能细节上可能会稍有区别)于x=x+3,其他复合赋值运算符与此类似。
python不支持++和–运算符,虽然形式上有时似乎可以遮掩共,但实际上是另外的含义,要注意和其他语言的区别。
>>> i=3
>>> ++i #正正得正,等价于+(+i)
3
>>> +(+3) #与++i等价
3
>>> i++ #python不支持++运算符,语法错误
File "<stdin>", line 1
i++
^
SyntaxError: invalid syntax
>>> --i #负负得正,等价于-(-i)
3
>>> ---i #等价于-(-(-i))
-3
>>> i-- #python不支持--运算符,语法错误
File "<stdin>", line 1
i--
^
SyntaxError: invalid syntax
>>> -----(3+5)
-8
>>> 3--5 #等价于3-(-5)
8
>>> 3+-5 #等价于3+(-5)
-2
>>> 3-+5
-2
1.4 比较运算符(关系运算符)
python关系运算符可以连用,其含义与人们日常的理解完全一致。使用关系符的一个最重要的前提是,操作数之间必须可比较大小。例如,把一个字符串和一个数字精心大小比较是毫无意义的,所以,python也不支持这样的运算。
>>> 1<3<5 #等价于1<3 and 3<5
True
>>> 3<5>2
True
>>> 1<6>8
False
>>> 1>6<math.sqrt(9) #具有惰性求值或者逻辑短路的特点
False
>>> 1<6<math.sqrt(9) #还没有导入math模块,抛出异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> import math
>>> a<6<math.sqrt(9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 1<6<math.sqrt(9)
False
>>> 'Hello'<'world' #比较字符串大小
True
>>> [1,2,3]<[1,2,4] #比较列表大小
True
>>> 'Hello'>3 #字符串和数字不能比较
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'int'
>>> {1,2,3}<{1,2,3,4} #测试是否为子集
True
>>> {1,2,3}=={3,2,1} #测试两个集合是否相等
True
>>> {1,2,4}>{1,2,3} #集合之间的包含测试
False
>>> {1,2,4}<{1,2,3}
False
>>> {1,2,4}=={1,2,3}
False
1.5 逻辑运算符
裸机运算符and,or,not常用来连接表达式构成更加复杂的条件表达式,并且and和or具有惰性求值或逻辑短路的特点,当连接多个表达式时只计算必须要计算的值。例如:表达式exp1 and exp2 等价于 exp1 if not exp1 else exp2,而表达式exp1 or exp2 则等价于exp1 if exp1 else exp2。再编写复杂条件表达式是充分利用这个特点,合理安排不同条件的先后顺序,在一定程度上可以提高代码的运行程度。另外要注意的是,运算符and和or并不一定会返回True和False,而是得到最后一个被计算的表达式的值,但是运算符not一定会返回True或False。
1.5.1 not 逻辑非
Not可以对符号右侧的值进行非运算对于布尔值,非运酸会对其进行取反操作,True变False,False变True。
1.5.2 and逻辑与
(1)and可以对符号两侧的值进行与运算。只有在符号两侧的值都为True时,才会返回True,只要有一个False就返回False。
(2)与运算是找False的,如果第一个值为False,则不再看第二个值。
1.5.3 or 逻辑或
(1)或运算两个值只要有一个True,就会返回True。
(2)或运算是找True的。
1.5.4 非布尔值的与或运算
(1)当我们对非布尔值进行与或运算的时候,python会将其当做布尔值运算,最终会返回原值。
(2)非布尔值与运算的规则:
· 与运算是找False的,如果第一个值是False,则不看第二个值。如果第一个值是False,则直接返回第一个值,否则返回第二个值。
(3)非布尔值或运算的规则
或运算是找True的,如果第一个值是True,则不看第二个值。如果第一个值是True,则直接返回第一个值,否则返回第二个值。
示例:
>>> 3>5 and a>3 #注意,此时并没有定义变量a
False
>>> 3>5 or a>3 #3>5的值为False,所以需要计算后面的表达式
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 3<5 or a>3 #3<5的值为True,不需要计算后面的表达式
True
>>> 3 and 5 #最后一个计算的表达式的值作为整个表达式的值
5
>>> 3 and 5>2
True
>>> 3 not in [1,2,3] #逻辑非运算not
False
>>> 3 is not 5 #not的计算结果只能是True和False
True
>>> not 3
False
>>> not 0
True
1.6 条件运算符(三元运算符)
条件运算符在执行时,会先对条件表达式进行求职判断。
如果判断结果为True,执行语句1,并返回执行结果
如果判断结果为False,执行语句2,并返回执行结果
语法:语句1 if 条件表达式 else 语句2
1.7 矩阵乘法运算符@
从python3.5开始增加了一个新的矩阵相乘运算符@,不过由于Python没有内置的矩阵类型,所以该运算符常与扩展库numpy一起使用。另外,@符号还可以用来表示修饰器的用法。
>>> import numpy #numpy是用于科学计算的python扩展库
>>> x=numpy.ones(3) #ones()函数用于生成全1的矩阵,参数表示矩阵大小
>>> m=numpy.eye(3)*3 #eye()函数用于生成单位矩阵
>>> m[0,2]=5 #设置矩阵指定位置上元素的值
>>> m[2,0]=3
>>> x@m #矩阵相乘
array([6., 3., 8.])
1.8 成员测试运算符in与同一性测试运算符is与同一性测试运算符is
成员测试运算符in用于成员测试,即测试一个对象是否为另一个对象的元素。
>>> 3 in [1,2,3]
True
>>> 5 in range(1,10,1)
True
>>> 'abc' in 'abcdefg'
True
>>> for i in {3,5,7}:
... print(i,end='\t')
...
3 5 7 >>>
同一性测试运算符is用来测试两个对象是否同一个,如果是则返回True,否则返回False。如果两个对象是同一个,两者具有相同的内存地址。
>>> 3 is 3
True
>>> x=[300,300,300]
>>> x[0] is x[1] #基于值的内存管理,同一个值在内存中只有一份
True
>>> x=[1,2,3]
>>> y=[1,2,3]
>>> x is y #上面形式创建的x和y不是同一个列表对象
False
>>> x[0] is y[0]
True
>>> x.append(4) #不影响列表y的值
>>> x
[1, 2, 3, 4]
>>> y
[1, 2, 3]
>>> x=y #x和y指向一个对象
>>> x is y
True
>>> x.append(4) #对x操作会对y造成同样的影响
>>> x
[1, 2, 3, 4]
>>> y
[1, 2, 3, 4]
1.9 位运算符和集合运算符
位运算符只能用于整数,其内部执行过程为:首先将整数转换为二进制数,然后右对齐,必要时左侧补0,按位进行运算,最后再把计算结果转换为十进制数字返回。位与运算规则为1&1=1,1&0=0&1=0&0=0,位或运算规则为1|1=1|0=0|1=1,0|0=0,位异或运算规则为1^1=0 ^ 0=0 ^1 =1,另外,左移位时右侧补0,没左移一位相当于乘以2,右移位时左侧补0,每右移一位相当于整除以2。
>>> 3<<2 #把3左移两位
12
>>> 3&7 #位与运算
3
>>> 3|8 #位或运算
11
>>> 3^5 #位异或运算
6
集合的交集,并集,对称差集等运算结束语运算符来实现,而差集则使用减号运算符实现(注意:并集运算不是加号)
>>> {1,2,3}|{3,4,5} #并集,自动去除重复元素
{1, 2, 3, 4, 5}
>>> {1,2,3}&{3,4,5} #交集
{3}
>>> {1,2,3}^{3,4,5} #对称差集
{1, 2, 4, 5}
>>> {1,2,3}-{3,4,5} #差集
{1, 2}
1.10 运算符优先级
算术运算符的优先级最高,其次是位运算符,成员测试运算符,关系运算符,逻辑运算符,算术运算符遵循“先乘除,后加减”的基本运算原则。