python:hashable

什么是hashable

官方解释:

  • 如果一个对象在其生命周期内,其哈希值从未改变(这需要一个__hash__()方法),并且可以与其他对象进行比较(这需要一个__eq__()或__cmp__()方法),那么这个对象就是可哈希的。哈希对象的相等意味着其哈希值的相等。
  • 哈希性使得对象可以用作dictionary键和set成员,因为这些数据结构在内部使用了哈希值。
  • Python的所有不可变的内置对象都是可hashable的,但可变容器(如列表或字典)并非如此。对于用户定义的类的实例,默认情况下是可哈希的;它们都是不相等的,并且它们的哈希值都是id()。

不严谨但易懂的解释:

  • 一个对象在其生命周期内,如果保持不变,就是hashable(可哈希的)。
  • hashable ≈ immutable 可哈希 ≈ 不可变

在Python中:

  • list、set和dictionary 都是可改变的,比如可以通过list.append(),set.remove(),dict[‘key’] = value对其进行修改,所以它们都是不可哈希的;
  • 而tuple和string是不可变的,只可以做复制或者切片等操作,所以它们就是可哈希的。

场景

怎样在一个序列上面消除重复的值(不关心元素顺序)

>>> a
[1, 5, 2, 1, 9, 1, 5, 10]
>>> set(a)
{1, 2, 10, 5, 9}
>>>

怎样在一个序列上面消除重复的值(保持元素顺序)

  • 如果序列上的值都是hashable类型,那么可以利用集合或者生成器来解决这个问题
def dedupe(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)


print(list( dedupe([1, 5, 2, 1, 9, 1, 5, 10])))
"""
[1, 5, 2, 9, 10]
"""
# for i in dedupe([1, 5, 2, 1, 9, 1, 5, 10]):
#     print(i,"*********")


# 读取一个文件,消除重复行
with open(somefile,'r') as f:
for line in dedupe(f):
- 如果序列上的值不是hashable类型或者是要基于某个字段,那么
```py
# 这里的 key 参数指定了一个函数,将序列元素转换成 hashable 类型
def dedupe(items, key=None):
    seen = set()
    for item in items:
        val = item if key is None else key(item)
        if val not in seen:
            yield item
            seen.add(val)


a = [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
print(list(dedupe(a, key=lambda d: (d['x'],d['y']))))
"""
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
"""
print(list(dedupe(a, key=lambda d: d['x'])))
"""
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值