我想构建两个python集的交集,但我需要有一个自定义相等来执行此操作。 有没有办法指定"等于"直接做交叉时?例如,由于lambda表达式?
我知道有一种方法可以覆盖 eq ,但我必须在同一个班级上使用不同的"等号"进行多次交叉。
谢谢!
答案 0 :(得分:5)
<强>前言强>
您尝试做的事情通过使用正确的术语来完善数学意义。你所指的“平等”实际上是equivalence relations。基本上,equicalenve关系描述了必须满足的条件,以便将集合中的两个元素标识为“等效”。
等价关系将一个集合分解为所谓的等价类。每个等价类是一个子集,包含原始集合中与等价关系成对等价的所有元素。
平等本身就是等价关系的一个特例。等式关系的每个等价类只包含一个元素,因为集合中的每个元素只等于它自己。
Excursion:在面向对象语言中谈到对象相等时,这是一个混乱的来源。在数学中,一个对象(即一个集合的成员)只存在一次(它只等于它自己)。然而,在面向对象编程中,存在身份和平等的区别。可以有相同的对象(Python:a is b
求值为false)相等(a == b
求值为true),例如float
2.0
和{{ 1}} int
。这意味着,Python的2
函数在所有Python对象的集合上实现了一个默认的等价关系,称为“相等”。 游览结束
任何等价类的一个更重要的事情是,它可以由一个任意成员(称为“代表”)表示。这意味着您只需要检查与等价类的一个已知代表的关系,以确定一个元素是否属于该等价类。这将在下面的代码中使用。
回答问题
对应您的问题,我们进行了以下设置。我们有两组__eq__
和A
,它们实际上是较大集合B
的子集。对于M
,存在许多不同的等价关系,对于每个等价关系,我们需要相对于等价关系“交叉”M
和A
“。
唯一有意义的方法是将B
和A
的成员替换为等价类,并检查两个投影中确实发生了哪些等效类。
这比听起来更容易:关于一个等价关系的交集配方:
B
(和A
)的元素进行分组,使每个组由成对等价元素组成。 (这些组类似于等价类)B
的每个小组G
,请检查A
的{{1}}群组是否属于H
和B
的元素是等价的。如果是,G
和H
属于同一等价类,即等价类是交集的成员。请注意,所需的输出实际上取决于您的用例。你可以,例如使用匹配G
和H
s的所有联合列表(这是下面要求的内容)。或者,如果您只对交集中每个等价类的任意元素感兴趣,则可以选择G
(或H
)的第一个成员。 (这在G
部分中显示为H
。)
下面的代码示例使用与任何对象和任何等价关系一起使用的列表(不是集合或代表)来实现如上所述的天真交集。 __main__
类接受一个带有两个参数的函数,如果两个参数是等价的,则返回true。
我假设您可以轻松优化用例以保存循环和比较。
重要提示:当然,你需要验证你的“平等”是否是真正的等价关系(反身性,对称性,及物性,见上面的维基链接)。
<强>代码:强>
[c[0] for c in intersection]
<强>输出:强>
Intersector
答案 1 :(得分:1)
一种方法是编写自己的Set
子类并以这种方式实现自定义比较。然后,您只需要为每个“相等”创建一个自定义“键控集”的新实例,您希望使用它来获得元素的交集。
例如:http://code.activestate.com/recipes/576932-sets-with-a-custom-equalityuniqueness-function/