核心对象类型复习和总结——比较、相等和为真

未匹配的标注

所有的Python对象都可以对比较操作进行响应:测试相等,相对数量大小等等。Python的比较总是检查复合对象的所有部分直到结果可以被确定。事实上,当嵌套对象出现时,Python自动地遍历数据结构来从左到右地应用比较,且按需要的那么深。在此过程中找到的第一个不同确定了比较结果。

这有时被称为递归的比较——在顶层对象上要求的相同比较被应用到每个嵌套对象,再对它们的嵌套对象,以此类推,直到比较结果被找到。本书稍后——在第19章——将学习如何编写我们自己的递归函数来类似地工作在嵌套结构上。现在,如果想要这种结构的暗喻和编写递归函数来处理它们的理由,请想一下比较两个网站上所有链接的页面。

就核心对象而言,递归是自动的。比如,列表对象的比较操作自动比较它们的所有组件直到不匹配被发现或到达对象末尾:

>>> L1 = [1, ('a', 3)] # Same value, unique objects
>>> L2 = [1, ('a', 3)]
>>> L1 == L2, L1 is L2 # Equivalent? Same object?
(True, False)

这里,L1 和 L2 都是被分配的列表,它们是等价但不同的对象。作为第6章中看过的一个预览,因为Python引用的本质,有两种测试相等的方法:

  • ==运算符测试值相等。Python执行一个相等测试,递归地比较所有嵌套的对象。
  • is 操作符测试对象相等性。Python测试是否这两个对象真的是同一个(也就是说,在内存中的同一个地址)。

在前面的例子中,L1 和 L2 通过了 == 测试(它们的值相等,因为其所有组件都是相等的)但 is 检查却失败了(它们引用了两个不同的对象,因此是两个不同的内存块)。然而,注意对短字符串发生了什么:

>>> S1 = 'spam'
>>> S2 = 'spam'
>>> S1 == S2, S1 is S2
(True, True)

这里,应该再次有两个碰巧有相同值的不同对象:== 应该为真,且 is 应该为假。但因为Python内在地缓存和重用一些字符串作为优化,这里其实只是一个在内存中,被S1和S2共享的字符串 'spam';因此,is 身份测试报告了一个真的结果。要触发正常行为,需要使用长一点的字符串:

>>> S1 = 'a longer string'
>>> S2 = 'a longer string'
>>> S1 == S2, S1 is S2
(True, False)

当然,因为字符串不可变,对象缓存机制和代码无关——字符串不能被就地修改,不管有多少个变量指向它们。如果身份测试看起来令人困惑,请参见第6章来复习对象引用的概念。

作为经验法则,对几乎所有相等检查,==都是你将要使用的;is是为高度专门化的角色保留的。在本书稍后将看到这两个操作符被用在哪里的例子。

相对大小比较也被递归地应用到嵌套数据结构:

>>> L1 = [1, ('a', 3)]
>>> L2 = [1, ('a', 2)]
>>> L1 < L2, L1 == L2, L1 > L2 # Less, equal, greater: tuple of results
(False, False, True)

这里,L1 比 L2大,因为嵌套的3比2大。到目前为止你应该知道最后一行的结果其实是3个对象的元组——三个键入的表达式的结果(一个元组不用其包裹小括号的例子)。

更具体地,Python比较类型如下:

  • 数字是按相对大小进行比较的,如果需要,要在转换到共同的最高类型后再进行比较(译注:比如有整型和浮点型,要先都转换为浮点型)
  • 字符串是按字典顺序来比较的(通过被ord返回的字符集码点值),逐个字符直到末尾或第一个不匹配处("abc" < "ac")。
  • 列表元组是通过从左到右比较每个组件来比较的,且对嵌套组件递归比较,直到最后或第一个不匹配处([2] > [1, 2])。
  • 如果两个sets包含同样的项,则它们相等(正式地讲,如果每个是另一个的子集),且set的相对大小比较使用子集和超集测试。
  • 如果字典的sorted(key,value)列表相等,则它们相等。对字典的相对大小比较在Python 3.X中不被支持,但它们在2.X中有效,好像在比较sorted(key, value)列表。
  • 非数字的混合类型大小比较(如:1 < 'spam')在3.X中是错误。它们在2.X中是允许的,但使用一个固定但任意的,基于类型名称字符串的排序规则。通过代理,这也应用于sorts,它内部使用了比较:非数字混合类型的集合在3.X中不能被排序。

通常,结构化对象的比较是这样进行的:好像已经把对象写为字面量,且从左到右一次一个地比较它们的所有部分。在后面的章节,还将看到可以改变它们被比较的方式的其它对象类型。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~