操作符概述

操作符概述

操作符可分为运算符(operators)和分隔符(delimiters)。

运算符有:

  • 数字运算符

+-***///%,详细用法见 数字运算

  • 整数按位运算符

<<>>&|^~,详细用法见 整数及其位运算

  • 比较运算符

<><=>===!=innot inisis not,详细用法见 比较运算符

  • 布尔运算符

andornot,详细用法见 布尔值及布尔运算

  • 赋值运算符 :=

Python 3.8 新增,将右边的表达式赋值给左边的变量, 同时返回表达式的值。

(a := 1+1)
2

运算符还分为一元运算符和二元运算符,一元运算符运算一个对象(操作数),二元运算符运算两个。一元运算符有 +(正数),-(负数),~(整数按位取反)和 not(布尔运算 非)。if ... else ... 有时称作三元运算符。

-1, +2, ~3, not 4
(-1, 2, -4, False)
1 + 2 - 3 * 4 # 二元运算符加、减和乘
-9
True if 2 > 3 else False
False

分隔符有:

()[]{},:.;=+=-=*=/=//=%=&=|=^=>>=<<=**=

部分分隔符用法举例:

圆括号绑定表达式,或元组显示,方括号用来对序列进行索引、切片取值或列表显示,花括号字典显示或集合显示

3 * (1 + 2) * (1,)
(1, 1, 1, 1, 1, 1, 1, 1, 1)
[1,2,3,4][1:3]
[2, 3]
{'列表':[], '集合':{1,2,3}}
{'列表': [], '集合': {1, 2, 3}}

上述分隔符 = 为赋值操作符,之后的操作符为增强赋值操作符,将名称绑定(或重新绑定)到特定值,以及修改属性或可变对象的成员项。 详见 赋值语句

假设将值 value1 绑定到名称 name,name = value1,则 name += value2 的结果相当于 name = name + value2,其他操作符类似。

举例如下:

a = 1
a += 1
a
2
b = 17
b |= 5
b
21

除了运算符和分隔符,还有 '"\# 字符,作为其他字符的组成部分时具有特殊含义,或是对词法分析器有重要意义。

'"\,详见 字符串概述转义字符

# 通常用来注释代码,但不能包含在字符串中,注释在语法分析中会被忽略:

# 这是注释
'''
# hello world
# hello python
'''
'\n# hello world\n# hello python\n'

操作符除了常规的用法,操作不同的数据类型,相应的数据类型可能定义了特定的操作规则;在特定的应用场景,也有着特殊的用法。详见 操作符特殊用法

比较运算符

比较运算符有 <><=>===!=innot inisis not

运算符 <>>=<===!= 比较两个对象的值,<>>=<= 称为次序比较;==!= 称为一致性比较。

由于所有类型都是 object 的(直接或间接)子类型,它们都从 object 继承了默认的比较行为,一致性比较是默认的比较行为,因此可在任何对象之间进行。

False == 0 != 'a' != int != {}
True

对象的值在 Python 中是一个相当抽象的概念:

  • 对象的值并没有一个规范的访问方法;
  • 对象的值并不要求具有特定的构建方式,例如由其全部数据属性组成等;
  • 比较运算符实现了一个特定的对象的值概念,可以认为正是通过实现对象比较,间接地定义了对象的值。

主要内置类型的比较行为:

1,数字类型内部可跨类型比较,按数学(算法)规则正确进行比较且不会有精度损失。但复数不支持次序比较。

True == 1 == 1.0
True
3.14 < 3
False
0 >= 0j
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-6-df80cad0b1a4> in <module>
----> 1 0 >= 0j


TypeError: '>=' not supported between instances of 'int' and 'complex'

2,字符串使用其字符的 Unicode 码位数字值依次进行比较,某个字符比较出大小即停止。如果一个字符串包含另一个,较短的排前面。

ord('a'), ord('b'), ord('c')
(97, 98, 99)
'a' == 'a', 'a' == 'c'
(True, False)
'ab' < 'ac'
True
'abc' > 'ab'
True

3,序列(列表,元组,range 实例)只能进行类型内部比较。跨类型一致性比较结果将是不相等,跨类型次序比较将引发 TypeError。range 不支持次序比较。

比较时按顺序对相应元素进行逐个比较,某个元素比较出大小即停止。如果一个序列元素包含另一个,较短的排前面。

(1,2) == [1,2]
False
[1,2] == [1,2]
True
[1,4] > [1,3,7]
True
[1,4] < [1,4,7]
True
(1,2) >= [1,2]
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-22-cb12354bca8e> in <module>
----> 1 (1,2) >= [1,2]


TypeError: '>=' not supported between instances of 'tuple' and 'list'

4, 两个字典若要相等,必须当且仅当它们具有相同的 键值对。次序比较将引发 TypeError。

{1:1} == {True:1.0}
True
{1:1} <= {True:1.0}
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-24-a13e7674e543> in <module>
----> 1 {1:1} <= {True:1.0}


TypeError: '<=' not supported between instances of 'dict' and 'dict'

5,集合 (set 或 frozenset 的实例) 可进行类型内部和跨类型的比较。

它们将比较运算符定义为子集和超集检测,具体详见集合知识点。这类关系没有定义完全排序。相应地,集合不适宜作为依赖于完全排序的函数的参数。

{1,2} == frozenset([1,2,1])
True
{3,1} > {1,2}
False
sorted([{3},{1},{2}])
[{3}, {1}, {2}]

运算符 innot in 用于成员检测。如果 x 是 s 的成员则 x in s 求值为 True,否则为 False。x not in s 返回 x in s 取反后的值。

所有内置序列和集合类型以及字典都支持此运算,对于字典来说 in 检测其是否有给定的键。

'a' in 'abc'
True
'abc' in 'abbc'
False
1 in [1,2]
True
[1] in [1,2]
False
'a' in {'a':1}
True

运算符 isis not 用于检测对象的标识号:当且仅当 x 和 y 是同一对象时 x is y 为真。一个对象的标识号可使用 id() 函数来确定。x is not y 会产生相反的逻辑值。

默认的一致性比较是基于对象的标识号。x is y 就意味着 x == y

a = 1
b = 1
a is b, a == b
(True, True)
a = (1,3)
b = (1,3)
a is b, a == b
(False, True)

操作符优先级

Python 表达式语句中操作符的优先顺序从最低优先级(最后绑定)到最高优先级(最先绑定)如下:

  • := 赋值表达式
  • lambda lambda 表达式
  • if -- else 条件表达式
  • or 布尔逻辑或 OR
  • and 布尔逻辑与 AND
  • not x 布尔逻辑非 NOT
  • in, not in, is, is not, <, <=, >, >=, !=, == 比较运算
  • | 按位或 OR
  • ^ 按位异或 XOR
  • & 按位与 AND
  • <<, >> 移位
  • +, - 加和减
  • *, /, //, % 乘,矩阵乘,除,整除,取余
  • +x, -x, ~x 正,负,按位非 NOT
  • ** 乘方(右边的先绑定)
  • await x await 表达式
  • x[index], x[index:index], x(arguments...), x.attribute 抽取,切片,调用,属性引用
  • (expressions...), [expressions...], {key: value...}, {expressions...} 绑定或加圆括号的表达式,列表显示,字典显示,集合显示

一个表达式语句中可以有多个上述操作符,最终返回一个值(包括返回值为 None 的函数调用)。

而赋值语句中的赋值操作符 =+=-=*=/=//=%=&=|=^=>>=<<=**=,在操作符中优先级最低,它右边表达式的值计算完之后,才最后绑定到左边的名称。

举例如下:

value = int('2')**(-1) == 2/(3+1)
value
True
int('2')**(-1) == 2/(3+1)
True
[].append(1) is None and not 1 - 1
True
value = 1 if 'a' in 'a b c'.split()[1:3] else 2
value
2
value **= 3 + 2 * 1
value
32

操作符 = 可以用来连续赋值:

a = b = c = 1
a,b,c
(1, 1, 1)

操作符特殊用法

容器类的内置类型,通常对操作符定义了自己特有的的操作行为。

  • * 操作符,除了数字运算的 乘,还可以用来将可迭代对象拆包。拆包之后置于元组,列表,集合中,或作为参数传递给函数:
{*{'a':1, 'b':2}}
{'a', 'b'}
print(*'abc', sep='-')
a-b-c
  • ++=**= 可用来对序列类型进行拼接,重复拼接或拼接并赋值(range 类型除外)。由于列表是可变对象,+=*= 在操作列表时,是用来更新列表。具体详见 列表操作符
'd-' + 'abc'*2
'd-abcabc'
a = [1]*2
a += [2]
a
[1, 1, 2]
  • 操作符 **||= 可以用来操作字典。具体详见 字典操作符

  • 操作符 ><>=<= 可对集合进行子集或超集比较;|&-^ 可求集合的并集,交集,差集,对称差集;|=&=-=^= 可用来更新集合。具体详见集合知识点。

  • 操作符 % 可以用来格式化字符串,而在格式化迷你语言中,定义了非常多的有特殊意义操作符。具体详见 str.format 格式化 和 字符串操作符