学习《Python Cookbook》第三版
如果序列上的值都是 hashable 类型,那么可以很简单的利用集合或者生成器来解决这个问题。比如:
def dedup(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
hashable_items = [1, 3, 2, 3, 6, 9]
print(list(dedup(hashable_items))) # [1, 3, 2, 6, 9]
这个方法仅仅在序列中元素为 hashable 的时候才管用。如果你想消除元素不可哈希 (比如 dict 类型) 的序列中重复元素的话,你需要将上述代码稍微改变一下,如:
def de_not_hash_dup(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)
这里的 key 参数指定了一个函数,将序列元素转换成 hashable 类型。下面是它的用法示例:
not_hash_items = [{'a': 1, 'b': 2}, {'a': 2, 'b': 3}, {'a': 1, 'b': 2}, {'a': 4, 'b': 2}]
print(list(de_not_hash_dup(not_hash_items, key=lambda x: (x.get('a'), x.get('b'))))) # [{'a': 1, 'b': 2}, {'a': 2, 'b': 3}, {'a': 4, 'b': 2}]
如果你想基于单个字段、属性或者某个更大的数据结构来消除重复元素,第二种方案同样可以胜任。
这里我们介绍下hashable的意思,官方解释:
An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method). Hashable objects which compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
All of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().
翻译过来的大概意思是:一个对象拥有一个哈希值(它需要一个hash()方法),并且在它的生命周期中从来不会改变,并且可以与其他对象做比较(对象需要一个eq()方法),那么这个对象就是可哈希的,就是hashable的。可哈希hashable的对象对比相同,则必定它们拥有相同的哈希值。
可哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值。
Python的所有不可变内置对象都是可哈希的;可变容器(如列表或字典)则不是。默认情况下,作为用户定义类实例的对象是可哈希的。它们的比较都是不相等的(除了它们自己),并且它们的散列值来自它们的id()。
dog = {'zhangsan': 1, 'lisi': 2}
print(id(dog)) # 2638136977304
dog['wangmazi'] = 3
print(id(dog)) # 2638136977304
cat = ('zhangsan', 1)
print(id(cat)) # 2638134634696
cat[2] = 2 # 报错 TypeError: 'tuple' object does not support item assignment
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved