【问题标题】:Python: Get most frequent item in listPython:获取列表中最常见的项目
【发布时间】:2013-09-20 14:18:03
【问题描述】:

给定一个元组列表,我希望获得最常出现的元组,但如果有“联合获胜者”,它应该在它们之间随机选择。

tups = [ (1,2), (3,4), (5,6), (1,2), (3,4) ]

上面的列表应该随机返回(1,2)(3,4)

【问题讨论】:

    标签: python list group-by max


    【解决方案1】:

    使用collections.Counter:

    >>> collections.Counter([ (1,2), (3,4), (5,6), (1,2), (3,4) ]).most_common()[0]
    ((1, 2), 2)
    

    这是O(n log(n))

    【讨论】:

    • 实际上,如果您需要最频繁的项目,可以在 O(n) 中完成。您只需计算频率,获取最大值,然后获取所有频率最高的项目。至少有 4 人不知道 :)
    • 不可能在 O(n) 中做到这一点,单独计算所有频率需要某种哈希表。
    • AFAIK Counter 实现为字典,字典的设置元素平均为O(1)。在您的回答中,most_common() 方法将对所有元素进行排序,因此它将是最重的部分 - O(n log(n))
    【解决方案2】:

    您可以先使用 Counter 查找重复次数最多的元组。然后找到需要的元组,最后随机化,得到第一个值。

    from collections import Counter
    import random
    
    tups = [ (1,2), (3,4), (5,6), (1,2), (3,4) ]
    lst = Counter(tups).most_common()
    highest_count = max([i[1] for i in lst])
    values = [i[0] for i in lst if i[1] == highest_count]
    random.shuffle(values)
    print values[0]
    

    【讨论】:

    • @Juddling 实际上,你不需要 most_common() - 看我的回答
    • @RomanPekar 我明白了,为什么我要避免使用 most_common()?
    • 如果我没记错的话,most_common() 会对整个列表进行排序,你只需要最大频率
    【解决方案3】:

    您可以首先对列表进行排序以获取按频率排序的元组。之后,线性扫描可以让您从列表中获得最频繁的元组。总时间O(nlogn)

    >>> tups = [ (1,2), (3,4), (5,6), (1,2), (3,4) ]
    >>> 
    >>> sorted(tups)
    [(1, 2), (1, 2), (3, 4), (3, 4), (5, 6)]
    

    【讨论】:

      【解决方案4】:

      这个人应该在o(n)时间完成你的任务:

      >>> from random import shuffle
      >>> from collections import Counter
      >>>
      >>> tups = [(1,2), (3,4), (5,6), (1,2), (3,4)]
      >>> c = Counter(tups)                            # count frequencies
      >>> m = max(v for _, v in c.iteritems())         # get max frq
      >>> r = [k for k, v in c.iteritems() if v == m]  # all items with highest frq
      >>> shuffle(r)                                   # if you really need random - shuffle
      >>> print r[0]
      (3, 4)
      

      【讨论】:

      【解决方案5】:

      collections.Counter 计数,然后随机选择最常见的:

      import collections
      import random
      
      lis = [ (1,2), (3,4), (5,6), (1,2), (3,4) ]  # Test data
      cmn = collections.Counter(lis).most_common()  # Numbering based on occurrence
      most = [e for e in cmn if (e[1] == cmn[0][1])]  # List of those most common
      print(random.choice(most)[0])  # Print one of the most common at random
      

      【讨论】:

        【解决方案6】:

        这是另一个没有导入的示例:

        listAlphaLtrs = ['b','a','a','b','a','c','a','a','b','c','c','b','a','a','a']
        dictFoundLtrs = {i:listAlphaLtrs.count(i) for i in listAlphaLtrs}
        maxcnt = 0
        theltr = 0
        for ltr in dictFoundLtrs:
            ltrfound = ltr
            foundcnt = dictFoundLtrs[ltr]
            if foundcnt > maxcnt:
                maxcnt = foundcnt
                theltr = ltrfound
        print('most: ' + theltr)
        

        来源:

        https://stackoverflow.com/a/23240989/1447509

        【讨论】:

          猜你喜欢
          • 2015-02-18
          • 2017-11-26
          • 1970-01-01
          • 2020-08-23
          • 2021-04-10
          • 1970-01-01
          • 2023-04-10
          • 2015-04-22
          相关资源
          最近更新 更多