比较两个不同的python计数器对象

时间:2018-09-14 01:50:09

标签: python algorithm comparison counter string-comparison

我正在研究Python中的算法,该算法将接受用户输入,并告诉他们需要将什么新字母添加到字符串中以使其变为不同的字符串,并且我一直在研究Counter方法创建的字典。

我想比较两个不同的字典,它们在计算字符串中的字母(例如使用collections模块中使用Counter工具返回的对象)。我们可以将这些字典称为D1和D2。我希望有两个结果字典(R1和R2),第一个是两者之间的共享字母,第二个是将R1变成R2所需的字母(在D2中但不在D1中的字母)。

例如:

# assuming they’ve been converted from counter objects into regular 
dictionaries #

D1 = {‘A’: 2, ‘B’: 1, ‘C’: 4, ‘D’: 5}
D2 = {‘A’: 3, ‘B’: 4, ‘C’ : 4, ‘D’: 7}

# Some sort of comparison function executed here #

结果:

R1={‘A’: 2, ‘B’: 3, ‘C’: 4, ‘D’: 5} 
R2 = {‘A’: 1, ‘B’: 1, ‘C’: 0 , ‘D’: 2} 

5 个答案:

答案 0 :(得分:3)

这些操作已内置在Counter类型中:

  

提供了几种数学运算来组合Counter对象以产生多组(计数大于零的counter)。加减法通过增加或减少相应元素的计数来组合计数器。交集和并集返回相应计数的最小值和最大值。

(引自Python collections.Counter docs。)

因此,假设D1D2是计数器,请尝试

R1 = D1 & D2
R2 = D2 - R1

答案 1 :(得分:3)

如果用共享字母表示计数器交叉点,则可以使用&运算符,将R1转换为R2所需的字母数量可以看作是区别:< / p>

from collections import Counter

D1 = Counter({'A': 2, 'B': 1, 'C': 4, 'D': 5})
D2 = Counter({'A': 3, 'B': 4, 'C': 4, 'D': 7})

R1 = D1 & D2

print(R1)  # intersection:  min(c[x], d[x])
print(D2 - D1)  # subtract (keeping only positive counts)

输出

Counter({'D': 5, 'C': 4, 'A': 2, 'B': 1})
Counter({'B': 3, 'D': 2, 'A': 1})

如果您想保留负数,可以这样做:

from collections import Counter

D1 = Counter({'A': 2, 'B': 1, 'C': 4, 'D': 5, 'E': 5})
D2 = Counter({'A': 3, 'B': 4, 'C': 4, 'D': 7, 'E': 3})

R2 = Counter({key: D2.get(key, 0) - value for key, value in D1.items()})
print(R2)

输出

Counter({'B': 3, 'D': 2, 'A': 1, 'C': 0, 'E': -2})

在上面的示例'E' : -2中,因为E5的计数是D1,在3中的计数是D2注意:所有示例均在Python 3.5中进行。

答案 2 :(得分:1)

IntersectCounter=[]
for each in D1:
        if D1[each]==D2[each]:
              IntersectCounter.append(each)

这在计数器D1和D2上提供了共同的内容

答案 3 :(得分:0)

我无法理解该问题,但据我了解:

R1 = {k: min(v, D2[k]) for k, v in D1.items()}
R2 = {k: abs(v - D2[k]) for k, v in D1.items()}

结果

>>> {k: min(v, D2[k]) for k, v in D1.items()}
{'A': 2, 'B': 1, 'C': 4, 'D': 5}
>>> {k: abs(v - D2[k]) for k, v in D1.items()}
{'A': 1, 'B': 3, 'C': 0, 'D': 2}

答案 4 :(得分:0)

自从Dani Mesejo回答以来,就添加了减法(docs),以便在Counter对象中保留负数(但是仅在原地),即以下是更简洁的解决方案:

from collections import Counter

D1 = Counter({'A': 2, 'B': 1, 'C': 4, 'D': 5, 'E': 5})
D2 = Counter({'A': 3, 'B': 4, 'C': 4, 'D': 7, 'E': 3})

R1 = D1 & D2
print(R1)  

D2.subtract(D1)
print(D2)

输出:

Counter({'D': 5, 'C': 4, 'E': 3, 'A': 2, 'B': 1})
Counter({'B': 3, 'D': 2, 'A': 1, 'C': 0, 'E': -2})