初级运算符在各种编程语言中都存在,在 Python 语言中还有一些高级运算符,这些高级运算符并不是所有的编程语言都支持的。
成员运算符
假设变量 val = "h", strone = "python"
,我们通过下面表格来了解成员运算符。
成员运算符 | 解释 | 例子 |
---|---|---|
in | 如果 val 的值在 strone 中存在返回 True,否则返回 False | val in strone 结果为 True |
not in | 如果 val 的值在 strone 中不存在返回 True,否则返回 False | val not in strone 结果为 False |
成员运算符运算的结果为布尔值,val 作为一个元素,可以是任何类型的对象,只要在 strone 中能找到 val,就会返回 True。
val = "hon" strone = "Python" print(val in strone)
身份运算符
身份运算符判断的是两个变量指向的对象的内存地址是否相同,Python 语言用 id 函数来获取变量指向的对象内存地址,我们通过如下表格了解身份运算符。
身份运算符 | 解释 | 例子 |
---|---|---|
is | is 是判断两个标识符是不是引用同一个对象 | a is b 等价于( id(a) == id(b) ) |
is not | is not 是判断两个标识符是不是引用不同对象 | a is not b 等价于(id(a) != id(b)) |
用身份运算符判断的是变量指向的对象的内存地址,要注意被不同变量指向的不同对象的值相等,对象内存地址不一定相等。
a = 5 aa = 5 b = 5.1 bb = 5.1 c = False cc = False d = None dd = None strone = "hello" strtwo = "hello" listone = [1, 2] listtwo = [1, 2] tupleone = (1, 2) tupletwo = (1, 2) tuplethree = (1, [2, 3]) tuplefour = (1, [2, 3]) print(a is aa) # True print(b is bb) # True print(c is cc) # True print(d is dd) # True print(strone is strtwo) # True print(listone is listtwo) # False print(tupleone is tupletwo) # True print(tuplethree is tuplefour) # False
注意:如上面代码,我们知道数字类型,布尔类型,NoneType 类型和字符串类型的值相同则 id 相同;list
类型的值相同而 id 不同;成员里面不含有变量的 tuple 类型对应的值相同则 id 相同,如果 tuple 里面的成员(或者成员的成员的…无限递归)出现有变量的话,虽然值相同,但 id 不同。
我们来好好分析一下:1.早期的 Python 解释器对布尔类型,数字类型,NoneType类型的变量都是通过分配不同的内存存储的,自从 Python 2.7 之后,解释器做了优化,所以那些类型只要值相同,所在的内存是同一个;
2.其实字符串类型的值是放在常量区,相同的字符串所在内存地址是一样的,也就是只要变量指向的字符串值相同,用的是同一块内存;
3.对于 list 类型所有的 Python 版本包括 Python 2 采用的都是一样的内存机制,就是无论 list 值是什么,在每一次创建的时候 Python 解释器都会重新分配一块内存;
4.对于 tuple 类型,Python 3.6(包括)之后的版本则会判断里面的成员(或者成员的成员的…无限递归)是否有变量,如果有的话则重新分配内存,否则共用一块内存,而 Python 2 采用的机制是只要创建一个新的 tuple 对象都会重新分配一块内存 。
大家注意到,我们上面所举的例子都是右值赋值的方式,如果是变量赋值呢,我们看下如下代码。
a = 5 aa = a b = 5.1 bb = b c = False cc = c d = None dd = d strone = "hello" strtwo = strone listone = [1, 2] listtwo = listone tupleone = (1, 2) tupletwo = tupleone tuplethree = (1, [2, 3]) tuplefour = tuplethree print(a is aa) # True print(b is bb) # True print(c is cc) # True print(d is dd) # True print(strone is strtwo) # True print(listone is listtwo) # True print(tupleone is tupletwo) # True print(tuplethree is tuplefour) # True
我只说一句:Python 解释器所有的变量之间赋值都是采用的浅拷贝方案,浅拷贝就是把赋值运算符(=
)右边的变量里面所指向值的内存地址直接赋值给左边的变量。
三目运算符
在其他语言(C,C++,Java)中三目运算符的表示方式是:判定条件? 为真时的结果: 为假时的结果。
在 python 语言中三目运算符的表示方式是:为真时的结果 if 判定条件 else 为假时的结果。
score = 59 print("ok" if score >= 60 else "no") # no
运算符优先级
当一个表达式中有多个不同种类的运算符时,要按运算符的优先级进行先后运算,我们通过如下表格了解运算符优先级。
运算符优先级 | 解释 |
---|---|
() | 最高优先级 |
** | 指数 |
~ + – | 按位翻转,一元的正号和负号 |
* / % // | 乘,除,取模,取整 |
+ – | 二元的加号和减号 |
>> << | 位右移和左移 |
& | 按位与 |
❘ ^ | 按位或运算和按位异或运算 |
> < >= <= | 大于,小于,大于等于,小于等于 |
== != <> | 等于和不等于 |
= += -= /= //= %= | 各种赋值 |
is is not | 身份运算 |
in not in | 成员运算 |
not | 逻辑取反运算 |
and | 逻辑与运算 |
or | 逻辑或运算 |
如果一条表达式中有多个不同种类型的运算符时,用小括号 () 括起来的先进行运算,总之我们没必要死记硬背这些运算符优先级。
sex = "man" score = 59 print(score >= 60 or sex == "man") # 糟糕的写法 print((score >= 60) or (sex != "man")) # 不错的写法
我们在写一个表达式的时候,尽量不要有多个不同种类型的运算符运算,避免代码可读性差,要把该表达式拆分多个只含有一个运算符的表达式。
sex = "man" score = 59 print(score >= 60 or sex == "man") # 糟糕的写法 scoreok = (score >= 60) man = (sex == "man") print(scoreok or man) # 很棒的写法
本节重要知识点
本节课讲的运算符运算属于高级运算符,要深入理解运算的对象和结果。
运算符优先级不要死记硬背,要学会写出可读性强的代码。
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » Python3高级运算符