Python中的元组排序和深度比较 (包括一些其他数据类型的操作)

参考https://treyhunner.com/2019/03/python-deep-comparisons-and-code-readability/

写得真的很牛B, 大佬,大佬,。

我按照它的原文摘出一些知识点

 

字符串可以比较

>>> "pear" == "pickle"
False
>>> "pear" != "pickle"
True
>>> "pear" < "pickle"
True
>>> "pear" > "pickle"
False

元组也可以比较

>>> target = (3, 6, 2)
>>> installed = (3, 7, 0)
>>> target == installed
False
>>> target <= installed
True
>>> target > installed
False

我的一点注释:

关于ascii表, 大概顺序是  数字 -->  大写字母   --> 小写字母  asc码逐渐增大
关于上面的元组和字符串比较,其实比较的的asc码的大小,从左往右比较asc码的大小,相同,则比较下一位。

还有长短不一致,但前缀相同的情况

>>> ("a", "b", "c") > ("a", "b")
True
>>> "ahc" > "ab"
True

就是前面都相同,长的较大

ord("")  返回asc码

 

关于列表

列表也可以比较,2019/8/31   紧急添加

>>> a = [1, 2, 3]
>>> b = [2, 3, 1]
>>> a == b
False

>>> a = [1, 2]
>>> b = [2, 2]
>>> a < b
True

 

关于集合

>>> a = {1, 2}
>>> b = {2, 1}
>>> a< b
False
>>> a == b
True

集合只能比较是否相等, 不能比较大小

 

关于字典

字典不能比较大小, 但是可以用 == , 看是否相等

说实话, 我没用到过 字典1 == 字典2 这样的操作

>>> a = {"a":"b", "c":"d"}
>>> b = {"c":"d", "a":"b"}
>>> a == b
True
>>> c = {"a":"b", "a":"b"}
>>> c
{'a': 'b'}
>>> d = {"a":"b", "a":"c"}
>>> d
{'a': 'c'}
>>> e =  {"a":"b", "a":"c", "a": "d"}
>>> e
{'a': 'd'}

另外:实测,字典的顺序, 不影响它们是否相等, 而且,但字典里键和值都相等时,python自动忽视,看成一个。

当键相等,值不同时,也会看成一个,而且值时最后一个也是最新的一个值。

 

 有几个小技巧

if self.x == other.x and self.y == other.y and self.z == other.z:


可以如下这样比较,更简洁

(self.x, self.y, self.z) == (other.x, other.y, other.z)

下一个例子

是说self.last 和self.first 小于other.last, other.first 才返回True, 剩下的等于什么的情况返回False 

下面的last优先于first,

def __lt__(self, other):
    if self.last_name < other.last_name:
        return True
    elif other.last_name < self.last_name:
        return False
    elif self.first_name < other.first_name:
        return True
    else:
        return False

可以优化成(注意and的优先级大于or

其实我不太理解

def __lt__(self, other):
    return (
        self.last_name < other.last_name or
        self.last_name == other.last_name and self.first_name < other.first_name
    )

 这个就很好理解了

def __lt__(self, other):
    return (self.last_name, self.first_name) < (other.last_name, other.first_name)

When you have code that compares two objects based on subparts in a particular order:

d1 = (1999, 12, 31)
d2 = (1999, 12, 1)
if d1[0] > d2[0]:
    greater = d1
elif d1[0] < d2[0]:
    greater = d2
elif d1[1] > d2[1]:
    greater = d1
elif d1[1] < d2[1]:
    greater = d2
elif d1[2] > d2[2]:
    greater = d1
else:
    greater = d2

You could probably rely on tuple ordering instead:

d1 = (1999, 12, 31)
d2 = (1999, 12, 1)
if d1 < d2:
    greater = d1
else:
    greater = d2

or

>>> d1 = (1999, 12, 31)
>>> d2 = (1999, 12, 1)
>>> d1[0] == d2[0] and d1[1] == d2[1] and d1[2] == d2[2]
False
>>> d1 = (1999, 12, 31)
>>> d2 = (1999, 12, 1)
>>> d1 == d2
False

 

Deep ordering(不知道为什么叫这个)

>>> fruits = ['kumquat', 'Cherimoya', 'Loquat', 'longan', 'jujube']
>>> def length_and_word(word): return (len(word), word.casefold())
...
>>> sorted(fruits, key=length_and_word)
['jujube', 'longan', 'Loquat', 'kumquat', 'Cherimoya']

批注:

Python casefold() 方法是Python3.3版本之后引入的,其效果和 lower() 方法非常相似,都可以转换字符串中所有大写字符为小写。

两者的区别是:lower() 方法只对ASCII编码,也就是‘A-Z’有效,对于其他语言(非汉语或英文)中把大写转换为小写的情况只能用 casefold() 方法。

sorted的key参数,是指定按什么排序,这里的key返回了两个数, 一个是长度,一个是小写字母。就是优先按长度升序排列,然后按asc升序排列。

下面只按asc排序

>>> sorted(fruits, key=len)
['Loquat', 'longan', 'jujube', 'kumquat', 'Cherimoya']

其实任何(maybe)有key参数的函数,都可这样排序。

>>> min(fruits, key=str.casefold)
'Cherimoya'
>>> max(fruits, key=str.casefold)
'Loquat'

 

Deep hashability (and unhashability)

主要说的是元组

元组是可以作为字典的键的,因为元组是可哈希的,集合里也是可以可以加元组的。

这个真的没细想过,元组作为字典的键。

>>> current_portals = {(1, 2): [(2, 1)], (2, 1): [(1, 2), (3, 4)]}
>>> points = {(1, 2), (2, 1), (3, 4)}

 

但是啊,可变元组就不能作为字典的键,比如元组里面套列表,元组里面每个对象都必须是可哈希的,列表是不可哈希的。

>>> things = {(["dress", "truck"], "yellow"), (["ball", "plane"], "purple")}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

 

虽然包含列表的元组是不哈希的,但是元组包含元组是可哈希的(感觉是废话)


>>> things = {(("dress", "truck"), "yellow"), (("ball", "plane"), "purple")}
>>> things
{(('dress', 'truck'), 'yellow'), (('ball', 'plane'), 'purple')}

 

元组通过分派给它们包含的项的哈希值来计算自身的哈希值:

>>> x = (1, 2)
>>> y = (1, 2)
>>> hash(x)
3713081631934410656
>>> hash(x) == hash(y)
True

Python支持深度哈希,这就是我们可以使用元组作为字典键的原因,也是我们可以在集合中使用元组的原因。

以上です

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值