在一个序列中保持元素顺序的同时消除重复的值

在一个序列中保持元素顺序的同时消除重复的值

首页休闲益智元素消除更新时间:2024-10-24

学习《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