【问题标题】:Python List FrequencyPython 列表频率
【发布时间】:2015-10-19 02:16:33
【问题描述】:

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


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

      您的诊断是正确的。第一次循环时,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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          【解决方案4】:

          skipping first item的来源

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-07-30
            • 2016-12-07
            • 1970-01-01
            • 1970-01-01
            • 2017-01-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多