collections.Counter: most_common INCLUDING equal counts

筅森魡賤 提交于 2019-12-20 01:46:38

问题


In collections.Counter, the method most_common(n) returns only the n most frequent items in a list. I need exactly that but I need to include the equal counts as well.

from collections import Counter
test = Counter(["A","A","A","B","B","C","C","D","D","E","F","G","H"])
-->Counter({'A': 3, 'C': 2, 'B': 2, 'D': 2, 'E': 1, 'G': 1, 'F': 1, 'H': 1})
test.most_common(2)
-->[('A', 3), ('C', 2)

I would need [('A', 3), ('B', 2), ('C', 2), ('D', 2)] since they have the same count as n=2 for this case. My real data is on DNA code and could be quite large. I need it to be somewhat efficient.


回答1:


You can do something like this:

from itertools import takewhile

def get_items_upto_count(dct, n):
  data = dct.most_common()
  val = data[n-1][1] #get the value of n-1th item
  #Now collect all items whose value is greater than or equal to `val`.
  return list(takewhile(lambda x: x[1] >= val, data))

test = Counter(["A","A","A","B","B","C","C","D","D","E","F","G","H"])

print get_items_upto_count(test, 2)
#[('A', 3), ('C', 2), ('B', 2), ('D', 2)]



回答2:


For smaller sets, just write a simple generator:

>>> test = Counter(["A","A","A","B","B","C","C","D","D","E","F","G","H"])
>>> g=(e for e in test.most_common() if e[1]>=2)
>>> list(g)
[('A', 3), ('D', 2), ('C', 2), ('B', 2)]

For larger set, use ifilter (or just use filter on Python 3):

>>> list(ifilter(lambda t: t[1]>=2, test.most_common()))
[('A', 3), ('C', 2), ('B', 2), ('D', 2)]

Or, since most_common are already ordered, just use a for loop and break on the desired condition in a generator:

def fc(d, f):
    for t in d.most_common():
        if not f(t[1]): 
            break
        yield t

>>> list(fc(test, lambda e: e>=2)) 
[('A', 3), ('B', 2), ('C', 2), ('D', 2)]


来源:https://stackoverflow.com/questions/26830929/collections-counter-most-common-including-equal-counts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!