当Python获取两个集合的交集时,它总是返回较小集合中的元素,这在几乎所有情况下都是合理的,但我试图做相反的事情。
在下面的代码片段中,请注意交集产生一个整数,而不是 float 。
[in] >>> x = {1.0,2.0,3.0}
[in] >>> y = {1}
[in] >>> x.intersection(y)
[out] >>> {1}
[in] >>> y.intersection(x)
[out] >>> {1}
如果我想恢复 float ,我必须使用一些大量的复制。
[in] >>> x - y
[out] >>> {2.0,3.0}
[in] >>> x - (x - y)
[out] >>> {1.0}
我正在处理比上面的示例大得多的集合。我的问题是是否有任何方法可以欺骗 Python set.intersection 方法从较大的集合中返回元素,或者除了我在这里所做的之外是否还有其他方法可以返回 float 1.0。
我首先这样做的原因是我试图通过子类化 freezeset 在纯 python 中实现卡住字典。我使用我称为“Item”的元组子类来存储键值对,其中 hash 仅返回键的哈希值。使用下面的代码,我可以创建一个其中包含单个键值对的集合。然后我提取属性“value”并返回它。
def __getitem__(self, key):
wrapped = Item((key,),flag=False)
if not frozenset.__contains__(self, wrapped):
raise KeyError(key)
matches = self - (self - {wrapped})
for pair in frozenset.__iter__(matches):
return pair.value
我知道复制是速度缓慢的原因,因为当我尝试返回键不在字典中的项目时,我会立即收到 KeyError,即使对于包含 1000 万个项目的集合也是如此。
最佳答案
冒着回答与您实际要求不同的问题的风险(但可能有助于实现最终目标)...《冰雪奇缘》字典实际上真的很容易在Python中实现:
from collections import Mapping
class FrozenDict(Mapping):
def __init__(self, *args, **kwargs):
self._hash = None # defer calculating hash until needed.
self._data = dict(*args, **kwargs)
def __getitem__(self, item):
return self._data[item]
def __len__(self):
return len(self._data)
def __iter__(self):
return iter(self._dict)
def __repr__(self):
return '{}({!r})'.format(type(self), self._data)
def __hash__(self):
if self._hash is not None:
return self._hash
# Only hashible if the items are hashible.
self._hash = hash(tuple(self.items()))
x = FrozenDict({'a': 'b'})
print x
x['c'] = 'Bad Bad Bad'
当然,这并不是真正卡住(与卡住集被卡住的含义相同)。用户可以访问并修改frozendict上的数据——但是他们应该承担他们造成的任何代码破坏。
<小时/>为了回答您的实际问题,我能想到的唯一选择是定义您自己的交集函数:
>>> s1 = set([1])
>>> s2 = set([1., 2.])
>>> def intersection(s1, s2):
... return set(x for x in s1 if x in s2)
...
>>> intersection(s1, s2)
set([1])
>>> intersection(s2, s1)
set([1.0])
这个总是返回集合,但是如果您假设第一个输入的类型具有仅接受可迭代的构造函数,则可以轻松修改以返回 freezeset 或输入的类型:
def intersection(s1, s2):
output_type = type(s1)
return output_type(x for x in s1 if x in s2)
关于Python集合交集,有什么方法可以从更大的集合中返回元素吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28115748/