Python列表与非唯一项目的交集

时间:2012-09-03 19:56:45

标签: python intersection multiset

我有两个字符串,我希望它们上的交集包括重复的项目:

str_a = "aabbcc"
str_b = "aabd"

list(set(str_a) & set(str_b))
>> "ab"

我想让它回归:

>> "aab"

有什么想法吗?

2 个答案:

答案 0 :(得分:18)

Multisets在python 2.7或更高版本中实现为(可变)Counter个对象。您可以对集合执行许多相同的操作,例如并集,交集,差异(尽管计数可能变为负数)等等:

from collections import Counter as mset

解决方案:

(mset("aabbcc") & mset("aabd")).elements()

更多详情:

>>> intersection = mset("aabbcc") & mset("aabd")
Counter({'a': 2, 'b': 1})

>>> list(intersection.elements())
['a', 'a', 'b']

>>> ''.join(intersection.elements())
'aab'

如果你想要一个字符串,你可以使用''.join;如果你想要一个列表,你可以使用list(),但我只能将其保存为intersection.elements()的可迭代格式。

答案 1 :(得分:9)

对每个单词使用collections.Counter并将其作为集合使用:

>>> from collections import Counter
>>> str_a, str_b = 'aabbcc', 'aabd'
>>> Counter(str_a) & Counter(str_b)
Counter({'a': 2, 'b': 1})
>>> ''.join((Counter(str_a) & Counter(str_b)).elements())
'aab'

Counter是一个dict子类,但它会计算用它初始化它的序列的所有元素。因此,"aabbcc"变为Counter({'a': 2, 'b': 2, 'c': 2})

计数器就像多重集合一样,当你在上面的交集中使用2时,它们的计数被设置为在任一计数器中找到的最小值,忽略计数下降到0的任何数据。如果你要计算它们的并集, 将使用最大计数。