ZetCode

Python 运算符

最后修改于 2024 年 1 月 29 日

在本文中,我们将介绍 Python 运算符。

运算符 是一个特殊的符号,表示要执行某个过程。编程语言中的运算符取自数学。应用程序处理数据。运算符用于处理数据。

在 Python 中,我们有几种类型的运算符

运算符可以有一个或两个操作数。操作数 是运算符的一个输入(参数)。只处理一个操作数的运算符称为一元运算符。处理两个操作数的运算符称为二元运算符。

加号和减号既可以作为加法和减法运算符,也可以作为一元符号运算符。这取决于具体情况。

>>> 2
2
>>> +2
2
>>>

加号可以用来表示我们有一个正数。但它通常不使用。减号会改变值的符号。

>>> a = 1
>>> -a
-1
>>> -(-a)
1

乘法和加法运算符是二元运算符的示例。它们与两个操作数一起使用。

>>> 3 * 3
9
>>> 3 + 3
6

Python 赋值运算符

赋值运算符 = 将值赋给变量。在数学中,= 运算符有不同的含义。在方程中,= 运算符是相等运算符。方程的左侧等于右侧。

>>> x = 1
>>> x
1

在这里,我们将一个数字赋给一个 x 变量。

>>> x = x + 1
>>> x
2

前面的表达式在数学上没有意义。但在编程中是合法的。该表达式的意思是我们给 x 变量加 1。右侧等于 2,并将 2 赋给 x

>>> a = b = c = 4
>>> print(a, b, c)
4 4 4

可以将一个值赋给多个变量。

>>> 3 = y
  File "<stdin>", line 1
SyntaxError: can't assign to literal

此代码示例会导致语法错误。我们不能将值赋给字面量。

Python 算术运算符

下表是 Python 编程语言中的算术运算符。

符号名称
+加法
-减法
*乘法
/除法
//整数除法
%取模
**功率

下面的示例展示了算术运算。

arithmetic.py
#!/usr/bin/python

# arithmetic.py

a = 10
b = 11
c = 12

add = a + b + c
sub = c - a
mult = a * b
div = c / 3

power = a ** 2

print(add, sub, mult, div)
print(power)

这些都是数学中的已知运算符。

$ ./arithmetic.py
33 2 110 4.0
100

有三个运算符涉及除法。

division.py
#!/usr/bin/python

# division.py

print(9 / 3)
print(9 / 4)
print(9 // 4)
print(9 % 4)

该示例演示了除法运算符。

print(9 / 4)

结果是 2.25。在 Python 2.x 中,/ 运算符是整数除法运算符。这在 Python 3 中已更改。在 Python 3 中,/ 运算符返回一个十进制数。

print(9 // 4)

// 运算符是 Python 3 中的整数运算符。

print(9 % 4)

% 运算符称为取模运算符。它查找一个数除以另一个数的余数。9 % 4,9 模 4 是 1,因为 4 除以 9 余 1,商是 2。

$ ./division.py
3.0
2.25
2
1
>>> 'return' + 'of' + 'the' + 'king'
'returnoftheking'

加法运算符也可用于连接字符串。

>>> 3 + ' apples'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

我们不能将整数和字符串相加。这会导致 TypeError

>>> str(3) + ' apples'
'3 apples'

为了使示例正常工作,我们必须使用 str 函数将数字转换为字符串。

另一方面,乘法运算符可用于字符串和数字。

>>> 'dollar ' * 5
'dollar dollar dollar dollar dollar '

Python 布尔运算符

在 Python 中,我们有 andornot 布尔运算符。我们使用布尔运算符执行逻辑运算。这些通常与 ifwhile 关键字一起使用。

andop.py
#!/usr/bin/python

# andop.py

print(True and True)
print(True and False)
print(False and True)
print(False and False)

此示例显示了逻辑与运算符。逻辑与运算符仅当两个操作数都为 True 时才评估为 True

$ ./andop.py
True
False
False
False

只要其中一个操作数为 True,逻辑或运算符就评估为 True

orop.py
#!/usr/bin/python

# orop.py

print(True or True)
print(True or False)
print(False or True)
print(False or False)

如果运算符的一侧为 True,则运算结果为 True

$ ./orop.py
True
True
True
False

否定运算符 notTrue 变为 False,将 False 变为 True

negation.py
#!/usr/bin/python

# negation.py

print(not False)
print(not True)
print(not ( 4 < 3 ))

该示例显示了 not 运算符的实际用法。

$ ./negation.py
True
False
True

and、or 运算符是短路求值的。短路求值意味着仅当第一个参数不足以确定表达式的值时,才会评估第二个参数:当 and 的第一个参数评估为 false 时,整个值必须为 false;当 or 的第一个参数评估为 true 时,整个值必须为 true。

以下示例演示了短路求值。

short_circuit.py
#!/usr/bin/python

# short_circuit.py

x = 10
y = 0

if (y != 0 and x/y < 100):
      print("a small value")

表达式的第一部分评估为 False。表达式的第二部分未被评估。否则,我们会得到一个 ZeroDivisionError

Python 关系运算符

关系运算符用于比较值。这些运算符始终产生布尔值。

符号含义
<严格小于
<=小于或等于
>大于
>=大于或等于
==等于
!=不等于
对象标识
不是否定的对象标识

上表显示了 Python 关系运算符。

>>> 3 < 4
True
>>> 4 == 3
False
>>> 4 >= 3
True

如前所述,关系运算符返回布尔值:TrueFalse

请注意,关系运算符不限于数字。我们也可以将它们用于其他对象。尽管它们可能不总是很有意义。

>>> "six" == "six"
True
>>> 'a' < 'b'
True

我们也可以比较字符串对象。

>>> 'a' < 'b'

这里到底发生了什么?计算机不知道字符或字符串。对它们来说,一切都只是一个数字。字符是特殊的数字,存储在特定的表中,如 ASCII。

>>> 'a' > 6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int()

无法对不同数据类型的变量使用关系运算符。此代码会导致 TypeError

compare.py
#!/usr/bin/python

# compare.py

print('a' < 'b')

print("a is:", ord('a'))
print("b is:", ord('b'))

在内部,a 和 b 字符是数字。因此,当我们比较两个字符时,我们是在比较它们存储的数字。内置的 ord 函数返回单个字符的 ASCII 值。

$ ./compare.py
True
a is: 97
b is: 98

实际上,我们比较的是两个数字:97 和 98。

>>> "ab" > "aa"
True

假设我们有一个包含更多字符的字符串。如果第一个字符相同,我们就比较下一个字符。在本例中,第二个位置的 b 字符比 a 字符的值大。这就是为什么 "ab" 字符串大于 "aa" 字符串。当然,以这种方式比较字符串没有太大意义。但技术上是可能的。

Python 对象标识运算符

对象标识运算符 isnot is 检查其操作数是否是同一个对象。

object_identity.py
#!/usr/bin/python

# object_identity.py

print(None == None)
print(None is None)

print(True is True)

print([] == [])
print([] is [])

print("Python" is "Python")

== 运算符测试相等性,而 is 运算符测试对象标识。即我们是否在谈论同一个对象。请注意,多个变量可能引用同一个对象。

$ ./object_identity.py
True
True
True
True
False
True

输出结果可能让您感到惊讶。在 Python 语言中,只有一个 None 对象和一个 True 对象。这就是为什么 True 等于 True,并且也标识于 True。毕竟,只有一种真相。空列表 [] 等于另一个空列表 []。但它们不是相同的。Python 将它们放入了两个不同的内存位置。它们是两个不同的对象。因此 is 运算符返回 False

另一方面,"Python" is "Python" 返回 True。这是因为优化:如果两个字符串字面量相等,它们就被放在了同一个内存位置。由于字符串是不可变的实体,因此不会造成任何损害。

Python 成员运算符

成员运算符 innot in 测试序列(如字符串、列表或元组)中的成员资格。

membership.py
#!/usr/bin/python

# membership.py

items = ("coin", "book", "pencil", "spoon", "paper")

if "coin" in items:
    print("There is a coin in the tuple")
else:
    print("There is no coin in the tuple")

if "bowl" not in items:
    print("There is no bowl in the tuple")
else:
    print("There is a bowl in the tuple")

使用成员运算符,我们测试一个项是否存在于元组中。

if "coin" in items:

使用 in 运算符,我们检查 "coin" 是否存在于 items 元组中。

if "bowl" not in items:

使用 not in 运算符,我们检查 "bowl" 是否不存在于 items 元组中。

$ ./membership.py
There is a coin in the tuple
There is no bowl in the tuple

Python 三元运算符

三元运算符是一个简单的简洁条件赋值语句。

exp1 if condition else exp2

如果条件为真,则计算 exp1 并返回结果。如果条件为假,则计算 exp2 并返回其结果。

ternary.py
#!/usr/bin/python

# ternary.py

age = 31

adult = True if age >= 18 else False

print("Adult: {0}".format(adult))

在许多国家,成年以年龄为基础。如果你超过某个年龄,你就是成年人。这就是三元运算符适用的情况。

adult = True if age >= 18 else False

首先评估条件。如果年龄大于或等于 18,则返回 True。否则,返回 else 关键字后面的值。然后将返回值赋给 adult 变量。

$ ./ternary.py
Adult: True

一个 31 岁的人是成年人。

Python 位运算符

十进制数对人类来说很自然。二进制数是计算机的本机。二进制、八进制、十进制或十六进制符号只是同一数字的不同表示法。位运算符对二进制数的位进行操作。我们有二进制逻辑运算符和移位运算符。位运算符很少在 Python 等高级语言中使用。

符号含义
~按位取反
^按位异或
&按位与
|按位或
<<左移
>>右移

按位取反运算符 将每个 1 变为 0,将 0 变为 1。

>>> ~7
-8
>>> ~-8
7

该运算符会翻转数字 7 的所有位。其中一位也决定了该数字是否为负数。如果我们再次对所有位进行取反,我们会得到数字 7。

按位与运算符对两个数字执行逐位比较。只有当操作数中对应的位都为 1 时,结果的该位才为 1。

     00110
  &  00011
   = 00010

第一个数字是 6 的二进制表示,第二个是 3,最终结果是 2。

>>> 6 & 3
2
>>> 3 & 6
2

按位或运算符对两个数字执行逐位比较。当操作数中对应的位任一为 1 时,结果的该位为 1。

     00110
  |  00011
   = 00111

结果是 00110 或十进制的 7。

>>> 6 | 3
7

按位异或运算符对两个数字执行逐位比较。当操作数中对应的位任一为 1 但不是两者都为 1 时,结果的该位为 1。

     00110
  ^  00011
   = 00101

结果是 00101 或十进制的 5。

>>> 6 ^ 3
5

如前所述,位运算符很少在 Python 和其他高级语言中使用。但有些情况下它们会被使用。一个例子是掩码。掩码是特定的位模式。它决定了某个属性是否已设置。

让我们举一个 GUI 编程的例子。

bitwise_or.py
#!/usr/bin/python

# bitwise_or.py

import wx

app = wx.App()
window = wx.Frame(None, style=wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
	| wx.SYSTEM_MENU | wx.CAPTION |	 wx.CLOSE_BOX)
window.Show(True)

app.MainLoop()

这是一个 wxPython 代码的小示例。wx.MAXIMIZE_BOXwx.RESIZE_BORDERwx.SYSTEM_MENUwx.CAPTIONwx.CLOSE_BOX 是常量。按位或运算符将所有这些常量添加到掩码中。在本例中,所有这些属性都使用按位或运算符设置,并应用于 wx.Frame 小部件。

最后,我们还有位移位运算符。位移位运算符 将位向右或向左移。

number << n : multiply number 2 to the nth power
number >> n : divide number by 2 to the nth power

这些运算符也称为算术移位。

     00110
  >> 00001
   = 00011

我们将数字六的每一位向右移动。这相当于将六除以 2。结果是 00011 或十进制 3。

>>> 6 >> 1
3
     00110
  << 00001
   = 01100

我们将数字六的每一位向左移动。这相当于将数字六乘以 2。结果是 01100 或十进制 12。

>>> 6 << 1
12

Python 复合赋值运算符

复合赋值运算符由两个运算符组成。它们是简写运算符。

>>> i = 1
>>> i = i + 1
>>> i
2
>>> i += 1
>>> i
3

+= 复合运算符是这些简写运算符之一。

其他复合运算符是

-=   *=   /=   //=   %=   **=   &=   |=   ^=   >>=   <<=

Python 运算符优先级

运算符优先级告诉我们哪些运算符首先被求值。优先级级别对于避免表达式中的歧义是必需的。

以下表达式的结果是 28 还是 40?

3 + 5 * 5

就像在数学中一样,乘法运算符的优先级高于加法运算符。所以结果是 28。

(3 + 5) * 5

要更改求值顺序,我们可以使用方括号。方括号内的表达式始终首先求值。

下表显示了 Python 中的运算符优先级。

unary +  -  ~
**
*  /  %
+  -
>>  <<
&
^
|
<  <=  ==  >=  >  !=  is
not
and
or

同一行的运算符具有相同的优先级级别。优先级从下到上递增。

precedence.py
#!/usr/bin/python

# precedence.py

print(3 + 5 * 5)
print((3 + 5) * 5)

print(2 ** 3 * 5)
print(not True or True)
print(not (True or True))

在此代码示例中,我们展示了一些常见的表达式。每个表达式的结果都取决于优先级级别。

print(2 ** 3 * 5)

幂运算符的优先级高于乘法运算符。首先,计算 2 ** 3,结果为 8。然后将结果乘以 5,最终结果为 40。

print(not True or True)

在这种情况下,not 运算符的优先级更高。首先,第一个 True 值被否定为 False,然后 or 运算符将 FalseTrue 组合起来,最终得到 True

$ ./precedence.py
28
40
40
True
False

关系运算符的优先级高于逻辑运算符。

positive.py
#!/usr/bin/python

# positive.py

a = 1
b = 2

if (a > 0 and b > 0):
   print("a and b are positive integers")

and 运算符等待两个布尔值。如果其中一个操作数不是布尔值,我们会收到语法错误。在 Python 中,关系运算符的求值先于逻辑与。

$ ./positive.py
a and b are positive integers

Python 结合律

有时优先级不足以确定表达式的结果。还有另一个规则称为结合律。运算符的结合律决定了具有相同优先级级别的运算符的求值顺序。

9 / 3 * 3

这个表达式的结果是 9 还是 1?乘法、除法和模运算符是从左到右结合的。所以表达式的求值方式是:(9 / 3) * 3 结果是 9。

算术、布尔、关系和位运算符都是从左到右结合的。

另一方面,赋值运算符是右结合的。

>>> a = b = c = d = 0
>>> a, b, c, d
(0, 0, 0, 0)

如果结合律是从左到右,那么前面的表达式将无法实现。

复合赋值运算符是右到左结合的。

>>> j = 0
>>> j *= 3 + 1
>>> j
0

您可能期望结果是 1。但实际结果是 0。这是因为结合律。表达式在右侧先求值,然后应用复合赋值运算符。

来源

Python 表达式 - 语言参考

在本文中,我们讨论了 Python 中的运算符。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Python 教程