我正在尝试检索列表中最常见且频率较低的元素。
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
模块并尝试更加面向逻辑的解决方案
没有收藏,你可以帮我做吗?
答案 0 :(得分:2)
您可以使用try
和except
方法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
默认值来对事件进行求和
单个数字,以及[]
,无效列表,用于构建列表
具有给定频率的所有数字。