当前位置: 代码迷 >> python >> Python列表频率
  详细解决方案

Python列表频率

热度:108   发布时间:2023-06-13 14:06:30.0

我必须弄清楚如何打印频率集。 到目前为止,这是我的代码,但它一直跳过列表中的第一个数字。 我认为那是因为我以前是从data[0]开始的,但是我不知道该如何解决

def frequencies(data):

    data.sort()

    count = 0
    previous = data[0]

    print("data\tfrequency") # '\t' is the TAB character

    for d in data:
        if d == previous:
            # same as the previous, so just increment the count
            count += 1
        else:
            # we've found a new item so print out the old and reset the count
            print(str(previous) + "\t" + str(count))
            count = 1

        previous = d

Python带有一个内置的类型,可以为您计算频率。 这不能解决代码的原始问题,但是可以完成您想要的事情。

>>> data = [1,2,3,4,2,2,3,5]
>>> c = Counter(data)
>>> c
Counter({2: 3, 3: 2, 1: 1, 4: 1, 5: 1})
>>> for key in sorted(c.keys()):
...     print('{}\t{}'.format(key, c[key]))
...
1   1
2   3
3   2
4   1
5   1

您的诊断是正确的。 循环中的第一次, if d == previous将始终为True ,那么就永远不会打印出第一组。 (或者,更糟糕的是,如果列表为空,则previous = data[0]崩溃。)


完成工作的简单方法是使用 。 查看链接的文档以了解如何实现。

for datum, group in itertools.groupby(sorted(data)):
    print('{0}\t{1}'.format(datum, len(list(group))))

另外,我建议:

  • data.sort()更改为sorted(data) ,以避免调用者看到更改列表顺序的副作用。
  • 使用str.format()而不是通过两个显式的str()类型转换进行串联。

如果您想挽救现有的实现,快速的解决方法是为第一遍添加一个例外:

for i, d in enumerate(data):
    if i > 0 and d == previous:
        …

您甚至不必初始化countprevious

您确定要跳过第一个而不是最后一个吗? 现在,当您从一个数据值过渡到另一个数据值时,它似乎仅打印信息。 因此,如果整个文件是一个数据值(例如一堆1s),则您将永远不会点击“ else”语句,也不会打印。

您可以通过打印先前的值并在循环完成后最后计数一次来解决此问题。

您的第一个值仍应计数,因为您正在将“ previous”初始化为数据中的第一个值,因此,当您进入循环时,d == previous并增加计数。 该部分看起来像您期望的那样。

如果这不正确,您能否提供简单的输入/输出?

来源

from itertools import islice
for car in islice(cars, 1, None):
    # do something

对于连续值的计数,由200_success建议的不能解决问题(Count()也不是),因为它们不计算邻接,而是计算总计数。 但是,提出的问题是“频率”,可以使用Count()或groupby()进行计数。

第三种选择是使用dict(使用键作为输入的更好的价值获取时间):

from collections import defaultdict

appearances = defaultdict(int)
for curr in a:
    appearances[curr] += 1