Ben*_*ott 5 python python-2.x set-intersection
因此,存在一种通过set.intersection()计算两个集合的交集的简单方法.但是,我有以下问题:
class Person(Object):
def __init__(self, name, age):
self.name = name
self.age = age
l1 = [Person("Foo", 21), Person("Bar", 22)]
l2 = [Person("Foo", 21), Person("Bar", 24)]
union_list = list(set(l1).union(l2))
# [Person("Foo", 21), Person("Bar", 22), Person("Bar", 24)]
Run Code Online (Sandbox Code Playgroud)
(Object是我的ORM提供的基类,它实现了基本__hash__和__eq__功能,它基本上将类的每个成员添加到哈希.换句话说,__hash__返回的将是类的每个元素的哈希)
在这个阶段,我想只运行一个集合交叉运算.name,比如说Person('Bar', -1).intersection(union_list) #= [Person("Bar", -1), Person("Bar", 22), Person("Bar", 24)].(典型的.intersection()在这一点上不会给我什么,我不能重写__hash__或者__eq__对Person类,因为这会覆盖原有的并集(我认为)
在Python 2.x中执行此操作的最佳方法是什么?
编辑:请注意,该解决方案不具有依靠set.但是,我需要找到工会然后交叉点,所以感觉这对于一套是合适的(但我愿意接受使用你认为值得的任何魔法的解决方案,只要它能解决我的问题!)
听起来好像
>>> class Person:
... def __init__(self, name, age):
... self.name = name
... self.age = age
... def __eq__(self, other):
... return self.name == other.name
... def __hash__(self):
... return hash(self.name)
... def __str__(self):
... return self.name
...
>>> l1 = [Person("Foo", 21), Person("Bar", 22)]
>>> l2 = [Person("Foo", 21), Person("Bar", 24)]
>>> union_list = list(set(l1).union(l2))
>>> [str(l) for l in union_list]
['Foo', 'Bar']
Run Code Online (Sandbox Code Playgroud)
是你想要的,因为name你的独特钥匙?
我讨厌回答自己的问题,所以我会暂时推迟将其标记为“答案”。
事实证明,这样做的方法如下:
import types
p = Person("Bar", -1)
new_hash_method = lambda obj: hash(obj.name)
p.__hash__ = types.MethodType(new_hash_method, p)
for i in xrange(0, len(union_list)):
union_list[i].__hash__ = types.MethodType(new_hash_method, union_list[i])
set(union_list).intersection(p)
Run Code Online (Sandbox Code Playgroud)
它当然很脏并且依赖于types.MethodType,但它比迄今为止提出的最佳解决方案(glglgl 的解决方案)强度要低,因为我的实际union_list可能包含数千个项目,因此这将节省我每次运行时重新创建对象的麻烦这个交叉过程。
| 归档时间: |
|
| 查看次数: |
5523 次 |
| 最近记录: |