在不使用集合的情况下对事件进行计数。计数器

时间:2017-08-30 08:39:09

标签: python counting

我正在尝试检索列表中最常见且频率较低的元素。

frequency([13,12,11,13,14,13,7,11,13,14,12,14,14])

我的输出是:

([7], [13, 14])

我尝试过:

import collections
s = [13,12,11,13,14,13,7,11,13,14,12,14,14]
count = collections.Counter(s)
mins = [a for a, b in count.items() if b == min(count.values())]
maxes = [a for a, b in count.items() if b == max(count.values())]
final_vals = [mins, maxes]

但我不想使用collections模块并尝试更加面向逻辑的解决方案 没有收藏,你可以帮我做吗?

5 个答案:

答案 0 :(得分:2)

您可以使用tryexcept方法dict来模拟Counter

def counter(it):
    counts = {}
    for item in it:
        try:
            counts[item] += 1
        except KeyError:
            counts[item] = 1
    return counts

或者您也可以dict.get使用默认值0

def counter(it):
    counts = {}
    for item in it:
        counts[item] = counts.get(item, 0) + 1
    return counts

您应该在理解之外执行min()max()以避免重复计算该数量(该功能现在是O(n)而不是O(n^2)

def minimum_and_maximum_frequency(cnts):
    min_ = min(cnts.values())
    max_ = max(cnts.values())
    min_items = [k for k, cnt in cnts.items() if cnt == min_]
    max_items = [k for k, cnt in cnts.items() if cnt == max_]
    return min_items, max_items

这将按预期工作:

>>> minimum_and_maximum_frequency(counter([13,12,11,13,14,13,7,11,13,14,12,14,14]))
([7], [13, 14])

答案 1 :(得分:0)

data = [13,12,11,13,14,13,7,11,13,14,12,14,14]
occurrences = {}
for i in data:
     if i in occurrences.keys():
             occurrences[i] += 1
     else:
             occurrences[i] = 1

max_vals = [i for i in occurrences.keys() if occurrences[i] == max(occurrences.values())]
min_vals = [i for i in occurrences.keys() if occurrences[i] == min(occurrences.values())]

答案 2 :(得分:0)

s = [13,12,11,13,14,13,7,11,13,14,12,14,14]

occurrences = dict()

for item in s:

    occurrences[item] = occurrences.setdefault(item, 0) + 1

mins = [a for a, b in occurrences.items() if b == min(occurrences.values())]
maxs = [a for a, b in occurrences.items() if b == max(occurrences.values())]

final_vals = [mins, maxs]

来自defaultdict的{​​{1}}更适合替换collections来计算列表中项目的出现次数。但是因为你限制了Counter的使用。因此collections处理setdefault更为优雅。

答案 3 :(得分:0)

怎么样:

s = [13,12,11,13,14,13,7,11,13,14,12,14,14]
freq_low = s.count(min(s, key=s.count))
freq_high = s.count(max(s, key=s.count))
mins = [a for a in set(s) if s.count(a) == freq_low]
maxes = [a for a in set(s) if s.count(a) == freq_high]
final_vals = [mins, maxes]

答案 4 :(得分:0)

这是一个非常简单的解决方案,可能不是最有效的解决方案(?),而是一个简单的解决方案。

data = get_data()
freqs, numbers = {}, {}
for i in data:
    freqs[i] = freqs.get(i, 0) + 1
for n, c in freqs.items():
    numbers[c] = numbers.get(c, []) + [n]
counts = list(numbers.keys())
res = (numbers[min(counts)], numbers[max(counts)])

让我们详细了解上面脚本中的内容,让我们先来看看 您提供的示例数据

In [1]: data = [13,12,11,13,14,13,7,11,13,14,12,14,14]

我们将使用两个词典,

In [2]: freqs, numbers = {}, {}

第一个填充迭代data,其键是 data中的个别数字及其值是每个数字的频率 数据中的数字(参见freqs.get(…)的照片)

In [3]: for i in data: freqs[i] = freqs.get(i, 0) + 1

第二个只是第一个的逆转,关键是 频率和值是给定的数字列表 频率。

In [4]: for n, c in freqs.items(): numbers[c] = numbers.get(c, []) + [n]

In [5]: numbers
Out[5]: {1: [7], 2: [12, 11], 4: [13, 14]}

此时我们需要一个包含numbers键的列表,即 出现

In [6]: counts = list(numbers.keys())

因为我们感兴趣的是最小值和最大值 出现

In [7]: [numbers[min(counts)], numbers[max(counts)]]
Out[7]: [[7], [13, 14]]

脚注:字典的.get(key, default_value)方法 如果字典中不存在该键,则返回默认值, 我们使用此功能的0默认值来对事件进行求和 单个数字,以及[],无效列表,用于构建列表 具有给定频率的所有数字。