频率计数器在我更改之前正在排序列表,更改后应该何时排序

Frequency counter is sorting list before I change it, when it should sort after it changes

我有一个频率计数器,用于遍历时间列表并告诉我每个数字出现的频率。首先,我 运行 通过函数使用 int() 删除小数。我在底部用打印语句检查它,它工作正常。但出于某种原因,即使在我用 int() 更改值之后出现了频率问题。这是我的代码,我会给出一些输出。

from itertools import groupby
times = [1.23, 1.23, 2.56, 1.23, 1.23, 1.23, 1.23, 1.5, 4.32, 5.3, 2.5, 5.7, 3.4, 8.9, 8.9, 8.9]
newtimes = []
lentimes = len(times)


for time in times:
  #Rounds down every time
  time = int(time)
  #Adds time to new list
  newtimes.append(time)

setTimes = list(set(newtimes))


freqlist = [len(list(group)) for key, group in groupby(newtimes)]

print(newtimes)
print(lentimes)
print(setTimes)
print("Freqlist is " + str(freqlist))

输出如下:

[1, 1, 2, 1, 1, 1, 1, 1, 4, 5, 2, 5, 3, 8, 8, 8]
16
[1, 2, 3, 4, 5, 8]
Freqlist is [2, 1, 5, 1, 1, 1, 1, 1, 3]

我花了一段时间才弄清楚 freqlist 输出发生了什么,它做的一切都是正确的,但它做的是时间,而不是新时间(我们去掉小数点的地方),即使它应该在我们去掉之后小数点。有任何想法吗?谢谢!

问题是 itertools.groupby 仅适用于 连续的相似项目 。它需要一个排序的 input 才能按照您期望的方式工作。您也不需要创建中间列表;相反,您可以将 sum 与生成器表达式一起使用:

freqlist = [sum(1 for _ in group) for key, group in groupby(sorted(newtimes))]

排序需要 O(n log n) 时间。对于 O(n) 解决方案,您可以使用 collections.Counter:

from collections import Counter

d = Counter(map(int, times))

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

然后,如果您愿意,可以在按键排序后提取列表中的值:

keys, values = zip(*sorted(d.items()))

print(values)

(7, 2, 1, 1, 2, 3)