如何使用等效对象访问集合的元素?
如果我有一个对象与 Python 集合中的一个元素比较,但不是同一个对象,是否有合理的方法来获取对集合中对象的引用?用例将使用该集来识别和共享重复数据。
示例 (Python 2.7):
>>> a = "This is a string"
>>> b = "This is a string"
>>> a is b
False
>>> a == b
True
>>> s = set((a,))
>>> b in s
True
如何使用 b
和 s
获取对 a
的引用?我可以想到一种方法,但我不确定您得到的是 a
还是 b
是否不依赖于实现。 编辑:当 s 有多个元素时,这不起作用;交集很自然地实现了类似 [x for x insmaller_set if x inlarger_set]
>>> for x in set((b,)).intersection(s): c = x
...
>>> c is a
True
也许一个好的解决方法是使用将每个键映射到其自身的字典,而不是集合。
If I have an object that compares equal to an element of a Python set, but is not the same object, is there a reasonable way to get a reference to the object in the set? The use case would be using the set to identify and share duplicated data.
Example (Python 2.7):
>>> a = "This is a string"
>>> b = "This is a string"
>>> a is b
False
>>> a == b
True
>>> s = set((a,))
>>> b in s
True
How to get a reference to a
using b
and s
? I can think of one way, but I'm not sure if it is not implementation-dependent whether you get a
or b
. EDIT: This does not work when s has more than one element; intersection is quite naturally implemented something like [x for x in smaller_set if x in larger_set]
>>> for x in set((b,)).intersection(s): c = x
...
>>> c is a
True
Perhaps a good workaround would be to use a dict that maps each key to itself, instead of the set.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在 python-list 上发现了类似的问题: 从设置。参考get_equivalent(container, item) (Python Recipe)有一个聪明的答案。
技巧是为“key”对象构造一个包装器对象,并使用
in
运算符检查包装器是否在集合中。如果包装器哈希值等于键,则其 __eq__ 方法可以获得对集合中对象的访问权限,并保存对其的引用。讨论中的一个要点是,对于无法识别的类型,集合元素的__eq__
方法必须返回NotImplemented
,否则包装器的__eq__
可能无法获取叫。I found a similar question on python-list: Get item from set. There is a clever answer with reference to get_equivalent(container, item) (Python recipe).
The trick is to construct a wrapper object for the 'key' object, and check if wrapper is in the set using the
in
operator. If the wrapper hashes equal to the key, its__eq__
method can gain access to the object in the set, and save a reference to it. An important point from the discussion is that the__eq__
method of the set elements must returnNotImplemented
for unrecognized types, otherwise the wrapper's__eq__
may not get called.您的用例听起来像是字典的用例。使用与“外部”对象比较的对象的属性作为键,并使用所需对象本身作为值。
如果这是一个简单的用例,并且您可以进行线性搜索,但是,您可以做显而易见的事情 - 这不会太糟糕:
如果您需要您所要求的东西(我可以想知道一些用例) - 方法是创建一个自定义字典类,该类将集合作为其成员之一,对成员集合实现代理方法,并在字典和集合方法中保持字典和集合内容的同步。正确实施会非常耗时,但相对简单,并且时间复杂度为 O(1)。
如果必须复制对周围所有数据的引用不是问题(这是线性的,但可能比上面的直接搜索更糟糕),您可以使用
如下表达式:
Your use case sounds like it is a use case for dictionaries. Use, as keys, the attribute of the object that compares equal to the "foreign" object, and as values the desired objects themselves.
If it is a simple use case, and you can have a linear search, however, you could do the obvious - it would not be bad:
If you need what exactly what you ar asking for (I can wonder some use cases for that) - the way to go is to create a custom dictionary class that has a set as one of its members, do implement proxy methods to the member set, and in both dictionary and set methods, keeps sync of both the dictionary and set contents. This would be time consuming to implement right, but relatively straightforward, and have a O(1) time.
If having to copy references to all data around is not an issue (this is linear, but probably worst than the straightforward search above), you can use the expression
as in:
这是我通过利用“eq”和“contains”方法的行为制作的快速解决方案。代码注释(希望)是自我记录的,但它在其他方面非常简单。
正如示例所示,它适用于 set、dict 和 list,理论上也适用于任何实现“contains”的对象。
Here's a quick solution I made by exploiting the behavior of the 'eq' and 'contains' methods. Code comments are (hopefully) self documenting, but it's otherwise pretty simple.
As the example shows, it works for set, dict and list, and in theory could work for any object that implements 'contains'.