比较

比较 属于 Python

7 个练习

关于 比较

Python 中的比较运算符(也叫 Python 关系运算符)会查看两个操作数的_值_,并在 comparison 条件成立或不成立时返回布尔值 True 或 False。

下表列出了最常见的 Python 比较运算符:

运算符 运算 描述
> “大于” 如果 a 的值严格大于 b,则 a > b 为 True
< “小于” 如果 a 的值严格小于 b,则 a < b 为 True
== “等于” 如果 a 的值严格等于 b,则 a == b 为 True
>= “大于或等于” 如果 a > b,或者按值 a == b,则 a >= b 为 True
<= “小于或等于” 如果 a < b,或者按值 a == b,则 a <= b 为 True
!= “不等于” 如果 a == b 为 False,则 a != b 为 True
is “身份” 当 且仅当 a 和 b 是同一个_对象_时,a is b 为 True
is not “取反的身份” 当 且仅当 a 和 b 不是同一个_对象_时,a is not b 为 True
in “包含测试” 如果 a 是 b 的成员、子集或元素,则 a in b 为 True
not in “取反的包含测试” 如果 a 不是 b 的成员、子集或元素,则 a not in b 为 True

它们的优先级都相同(高于布尔运算,但低于算术运算或位运算)。

不同数据类型之间的比较

类型不同的对象(数值类型除外)默认永远不会比较为相等。 除非 class 定义了特殊的富比较方法,用来定制 object 的默认比较行为,否则同一个 class 的不同实例也_不会_比较为相等。 想了解(多得多)的细节,请参阅 Python 文档中的值比较。

数值类型(大多)是这个类型匹配规则的例外。 只要类型能够为比较而隐式转换,integer 可以被认为等于 float(或者 octal 等于 hexadecimal)。

对于其他数值类型(复数、小数、分数),比较运算符被定义在它们“说得通”的地方(也就是隐式转换不会改变结果的地方),但如果底层对象无法为比较而准确转换,就会抛出 TypeError。 关于 Python 数值转换所用规则的更多信息,请参阅 Python 文档中的算术转换。

>>> import fractions

# A string cannot be converted to an int.
>>> 17 == '17'
False

# An int can be converted to float for comparison.
>>> 17 == 17.0
True

# The fraction 6/3 can be converted to the int 2
# The int 2 can be converted to 0b10 in binary.
>>> 6/3 == 0b10
True

# An int can be converted to a complex 
# number with a 0 imaginary part.
>>> 17 == complex(17)
True

# The fraction 2/5 can be converted to the float 0.4
>>> 0.4 == 2/5
True

>>> complex(2/5, 1/2) == complex(0.4, 0.5)
True

数字与 NaN(非数字)类型之间的任何有序比较都是 False。 Python 对 NaN 的定义有一个令人困惑的副作用:NaN 永远不会比较为等于 NaN。 如果你好奇 Python 为什么这样定义 NaN,这篇围绕国际标准制定的 Stack Overflow 帖子 值得一读。

>>> x = float('NaN')

>>> 3 < x
False

>>> x < 3
False

# NaN never compares equal to NaN
>>> x == x
False

比较字符串

字符串(str)按字典序比较,依据的是它们各自的 Unicode 码点(也就是把 str 中每个码点传给内置函数 ord() 所得到的结果,该函数返回一个 int)。 如果两个字符串的所有码点都相同,并且_顺序也相同_,这两个字符串就被视为相等。 这种比较是“成对”进行的:第一个对第一个,第二个对第二个,依此类推。 在 Python 3.x 中,str 和 bytes 不能直接强制转换或比较。

>>> 'Python' > 'Rust'
False

>>> 'Python' > 'JavaScript'
True

# Examples with Mandarin.
# hello < goodbye
>>> '你好' < '再见'
True

# ord() of first characters
>>> ord('你'), ord('再')
(20320, 20877)

# ord() of second characters
>>> ord('好'), ord('见')
(22909, 35265)

# And with Korean words.
# Pretty < beautiful.
>>> '예쁜' < '아름다운'
False

>>> ord('예'), ord('아')
(50696, 50500)

比较容器数据类型

容器数据类型(lists、tuples、sets、dicts 等)也按字典序比较:如果两个容器有相同的数据并且有相同的数据类型,它们就相等(对于 lists 和 tuples,它们还必须具有相同的顺序),否则不相等。

>>> [1, 2] == [1, 2]
True

# But if the data is not in the same order, they are not equal.
>>> [2, 1] == [1, 2]
False

# The same holds true for tuples
>>> (3,4,5) == (5,4,3)
False

# Length is also compared
>>> [1, 2] < [1, 2, 3]
True

# Comparing dicts
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 18}
False

>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 19}
True

链式比较

比较运算符可以_任意_链式连接。 注意,表达式的求值是从 left 到 right 进行的。 例如,x < y <= z 等价于 x < y and y <= z,区别在于 y 只求值一次。 在这两种情况下,当发现 x < y 为 False 时,z 根本不会被_求值_。 这通常被称为 short-circuit evaluation:如果表达式的真值已经确定,求值就会停止。

许多布尔运算符、函数以及 Python 中的链式比较都支持 Short circuiting。 与 C、C++、C# 和 Java 等许多其他编程语言不同,Python 中像 a < b < c 这样的链式表达式具有传统的数学解释和优先级。

>>> x = 2
>>> y = 5
>>> z = 10

>>> x < y < z
True

>>> x < y > z
False

>>> x > y < z
False

身份比较

运算符 is 和 is not 测试的是对象的身份,而不是对象的_值_。 对象的身份在创建后永不改变,可以用 id() 函数获得。

当 且仅当 id(<apple>) == id(<orange>) 时,<apple> is <orange> 求值为 True。 <apple> is not <orange> 则得到相反的结果。

由于它们具有单例状态,None 和 NotImplemented 与条目比较时应该始终使用 is 和 is not。 关于这一约定的更多细节,请参阅 Python 参考文档中的值比较和 PEP8。


# A list of favorite numbers.
>>> my_fav_numbers = [1, 2, 3]

>>> your_fav_numbers = my_fav_numbers

>>> my_fav_numbers is your_fav_numbers
True

# The returned id will differ by system and Python version.
>>> id(my_fav_numbers)
4517478208

# your_fav_numbers is only an alias pointing to the original my_fav_numbers object.
# Assigning a new name does not create a new object.
>>> id(your_fav_numbers)
4517478208


>>> my_fav_numbers is not your_fav_numbers
False

>>> my_fav_numbers is not None
True

>>> my_fav_numbers is NotImplemented
False

成员关系比较

运算符 in 和 not in 测试的是_成员关系_。 如果 <fish> 是 <soup> 的成员(<fish> 是 <soup> 的子集,或被包含在 <soup> 中),<fish> in <soup> 求值为 True,否则求值为 False。 <fish> not in <soup> 返回相反的结果,也就是 <fish> in <soup> 的_反面_。

对于字符串和 bytes 类型,当且仅当 <name> 是 <fullname> 的子串时,<name> in <fullname> 为 True。


# A set of lucky numbers.
>>> lucky_numbers = {11, 22, 33}
>>> 22 in lucky_numbers
True

>>> 44 in lucky_numbers
False

# A dictionary of employee information.
>>> employee = {'name': 'John Doe', 'id': 67826, 'age': 33, 'title': 'ceo'}

# Checking for the membership of certain keys.
>>> 'age' in employee
True

>>> 33 in employee
False

>>> 'lastname' not in employee
True

# Checking for substring membership
>>> name = 'Super Batman'
>>> 'Bat' in name
True

>>> 'Batwoman' in name
False

对象的比较行为可以通过实现 rich comparison methods 来定制。 更多信息请参阅 Python 教程:类、Python Classes and Magic Methods (Dan Bader)和特殊方法名。

通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 比较

练习已锁定

再解锁 4 个练习即可练习 比较