【发布时间】:2013-09-07 22:27:45
【问题描述】:
我有一个Counter(来自collections)并想过滤掉一组不需要的项目。结果应该是一个新的 Counter (或者如果你喜欢,就地做),只包含与属性不匹配的项目。我尝试在Counter 上使用filter,但结果不再是Counter,而只是list。我还尝试从Counter 中减去不需要的项目的set,但该操作未实现。减去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})
现在我想从这个计数器中删除所有2 和3 值,所以结果应该是
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 一起使用?
【问题讨论】:
-
不会过滤列表并将其发送到 Counter 工作吗?
-
如果你的意思是像
Counter(filter(lambda x: x not in (2, 3), c))那么:不。过滤器迭代计数器,这意味着它只迭代键;金额在此过程中被遗忘。然后,每个剩余键的结果将始终为 1。 -
我的意思是你过滤这个列表
[ 1,2,3,4,5,6,7,6,5,4,3,2,3,4,5,6,5,4,3,4,5,4 ]并将它传递给计数器。 -
我没有那个列表(这里的小例子除外);它可能非常长。考虑像@987654344@ 这样的事情。我总是可以使用
c.elements()创建这个列表(正如我在上面的问题中所说),但我想避免这样做,因为它很昂贵。
标签: python collections filter counter subtraction