可爱的 Python: Python 之优雅与瑕疵,第 1 部分
2008-09-30 12:57:47 来源:WEB开发网清单 6. 集与集操作
>>> set1 = set([1j, u'2', 3, 4.0])
>>> set2 = set([4, 3, 2, 1])
>>> set1 | set2
set([3, 1, 2, 1j, 4.0, u'2'])
>>> set1 & set2
set([3, 4])
在编写上面这个示例时,我发现了一些相当奇怪的现象。集操作似乎采用相等性(equality)而不是同一性(identity)。或许这有某种意义,但奇怪的是,这两个集的合集包含浮点数 4.0,而其交集包含整数 4。更奇怪的是,尽管求合集和交集的操作在理论上是对称的,但是实际结果却与次序相关:
清单 7. 集中得到的奇怪类型
>>> set2 & set1
set([3, 4.0])
>>> set([3, 4.0, 4, 4+0j])
set([3, 4.0])
当然,初看起来,集是一种很棒的数据类型。但是,定制的比较总是应该考虑的解决方案。在 Python 2.4 之前,完全有可能实现定制的 cmp() 函数并将它传递给 list.sort()。这样就可以实现原本不可比较的对象之间的比较;cmp 自变量的问题是,每次比较时都要调用这个函数:Python 的调用开销非常高,而且更糟糕的是,要经过多次计算才能得出所计算的值。
对于 cmp 效率低下的问题,有效的解决方案是使用 Schwartzian 排序:修饰(decorate)各对象,进行排序,然后去掉修饰。遗憾的是,这需要使用一些定制的代码,不是简单地调用 list.sort() 就能够实现的。Python 2.4 提供了一种出色的组合解决方案,使用 key 自变量。这个自变量接受一个函数,这个函数返回一个经装饰的对象并 “在幕后” 进行 Schwartzian 排序。请记住,即便是复数与复数之间也不能进行比较,而 Unicode 对象只在与某些 字符串比较时会出问题。我们可以使用以下代码:
更多精彩
赞助商链接