Python列表频率

时间:2015-10-19 02:16:33

标签: python

我必须弄清楚如何打印频率集。到目前为止这是我的代码,但它一直跳过列表中的第一个数字。我认为那是因为我以前从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

4 个答案:

答案 0 :(得分:4)

Python附带内置Counter类型,可为您计算频率。这并不能解决代码的原始问题,但它可以完成您希望它执行的操作。

>>> 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

答案 1 :(得分:3)

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

完成工作的简单方法是使用itertools.groupby()。查看链接的文档,了解如何实现它。

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

答案 2 :(得分:0)

你确定它正在跳过第一个而不是最后一个吗?现在,当您从一个数据值跨越到另一个数据值时,它看起来只是打印信息。因此,如果整个文件是一个数据值(例如一堆1),您将永远不会点击“else”语句而永远不会打印。

您只需打印前一个值并在循环完成后最后一次计数即可解决此问题。

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

如果这不对,你能提供一个简单的输入/输出吗?

答案 3 :(得分:0)

skipping first item

的来源
from collections import defaultdict

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

对于连续值的计数,200_success建议的itertools.groupby()不起作用(Count()也没有),因为这些不计算邻接而是总计数。但是,提出的问题是“频率”,可以用Count()或groupby()来计算。

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

$container.imagesLoaded()