带过滤器或减法或类似的计数器

时间:2013-09-04 12:08:31

标签: python collections filter counter subtraction

我有Counter(来自collections)并希望过滤掉一组不需要的内容。结果应该是一个新的计数器(或者如果你愿意,就地进行)只包含与该属性不匹配的项目。我尝试在filter上使用Counter,但结果不再是Counter,而只是list。我还尝试从set中减去Counter个不需要的项目,但该操作未实现。减去Counter的工作,但我没有第二个Counter并且创建它本质上是我正在尝试执行的任务。

Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4 ])
→ Counter({4: 6, 5: 5, 3: 4, 6: 3, 2: 2, 1: 1, 7: 1})

现在我要从此计数器中删除所有23值,因此结果应为

Counter({4: 6, 5: 5, 6: 3, 1: 1, 7: 1})

以下是我的方法:

filter(lambda x: x not in (2, 3), c)
→ [1, 4, 5, 6, 7]

但我不想要一份清单。

c - set([ 2, 3 ])
→ TypeError: unsupported operand type(s) for -: 'Counter' and 'set'

我可以使用sth迭代Counter中解压缩的元素列表,如下所示:

Counter(x for x in c.elements() if x not in (2, 3))
→ Counter({4: 6, 5: 5, 6: 3, 1: 1, 7: 1})

但是对于大笔金额而言,这显然是不必要的。

我发现的唯一(不太好)的解决方案是这样的麻烦:

Counter({ k: v for k, v in c.iteritems() if k not in (2, 3) })

我有什么更好,更容易,更易读的东西?

为什么实现的Counter只有一个减法运算符,可以与set一起使用?

3 个答案:

答案 0 :(得分:3)

只需使用del

>>> c = Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4 ])
>>> c
Counter({4: 6, 5: 5, 3: 4, 6: 3, 2: 2, 1: 1, 7: 1})
>>> del c[2]
>>> del c[3]
>>> c
Counter({4: 6, 5: 5, 6: 3, 1: 1, 7: 1})
>>>

只是为了好玩,您可以使用较大的值减去另一个Counter要删除的键,但最好坚持使用del

>>> c = Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4 ])
>>> c
Counter({4: 6, 5: 5, 3: 4, 6: 3, 2: 2, 1: 1, 7: 1})
>>> c - Counter({2:sys.maxint, 3:sys.maxint})
Counter({4: 6, 5: 5, 6: 3, 1: 1, 7: 1})

答案 1 :(得分:1)

试试这个:

from collections import Counter
c=Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4 ])
c2=Counter()
for x in c.most_common():
    if x[1]<2 or x[1]>3:
        c2[x[0]]+=x[1]
print(c2)

答案 2 :(得分:0)

你可以使用pop - 它比使用del或词典理解更快。

def alt():
    C = Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4])
    for k in C.keys():
        if k in (2, 3):
            del C[k]

def alt2():
    C = Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4])
    for k in C.keys():
        if k in (2, 3):
            C.pop(k)

def alt3():
    C = Counter([ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4])
    Counter({ k: v for k, v in c.iteritems() if k not in (2, 3) })

IPython的:

>>> %timeit alt()
100000 loops, best of 3: 9.66 µs per loop

>>> %timeit alt2()
100000 loops, best of 3: 8.64 µs per loop

>>> %timeit alt3()
100000 loops, best of 3: 11.3 µs per loop