Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中按计数对多个列表的元素进行排序_Python_List_Set_Ranking_Rank - Fatal编程技术网

在Python中按计数对多个列表的元素进行排序

在Python中按计数对多个列表的元素进行排序,python,list,set,ranking,rank,Python,List,Set,Ranking,Rank,我想根据它们在每个列表中出现的频率对多个列表进行排序。例如: 列表1=1,2,3,4 列表2=4,5,6,7 列表3=4,1,8,9 结果=4,1,2,3,4,5,6,7,8(4计数三次,1计数两次,其余计数一次) 我试过以下方法,但我需要一些更智能的东西,并且我可以用任何数量的列表来做 l = [] l.append([ 1, 2, 3, 4, 5]) l.append([ 1, 9, 3, 4, 5]) l.append([ 1, 10, 8, 4, 5]) l.append([

我想根据它们在每个列表中出现的频率对多个列表进行排序。例如:

列表1=1,2,3,4
列表2=4,5,6,7
列表3=4,1,8,9

结果=4,1,2,3,4,5,6,7,8(4计数三次,1计数两次,其余计数一次)

我试过以下方法,但我需要一些更智能的东西,并且我可以用任何数量的列表来做


 l = []
 l.append([ 1, 2, 3, 4, 5])
 l.append([ 1, 9, 3, 4, 5])
 l.append([ 1, 10, 8, 4, 5])
 l.append([ 1, 12, 13, 7, 5])
 l.append([ 1, 14, 13, 13, 6])

 x1 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[3])
 x2 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[4])
 x3 = set(l[0]) & set(l[1]) & set(l[3]) & set(l[4])
 x4 = set(l[0]) & set(l[2]) & set(l[3]) & set(l[4])
 x5 = set(l[1]) & set(l[2]) & set(l[3]) & set(l[4])
 set1 = set(x1) | set(x2) | set(x3) | set(x4) | set(x5)

 a1 = list(set(l[0]) & set(l[1]) & set(l[2]) & set(l[3]) & set(l[4]))
 a2 = getDifference(list(set1),a1)
 print a1
 print a2
现在问题来了。。。我可以用a3,a4和a5一次又一次地做,但它太复杂了,我需要一个函数来完成这个。。。但我不知道怎么。。。我的数学被卡住了;)

解决:非常感谢您的讨论。作为一个新手,我喜欢这个系统:快速+信息。你帮了我所有的忙!泰

import collections

data = [
  [1, 2, 3, 4, 5],
  [1, 9, 3, 4, 5],
  [1, 10, 8, 4, 5],
  [1, 12, 13, 7, 5],
  [1, 14, 13, 13, 6],
]

def sorted_by_count(lists):
  counts = collections.defaultdict(int)
  for L in lists:
    for n in L:
      counts[n] += 1

  return [num for num, count in
          sorted(counts.items(),
                 key=lambda k_v: (k_v[1], k_v[0]),
                 reverse=True)]

print sorted_by_count(data)
现在,让我们对其进行概括(采用任何iterable,放宽哈希要求),允许键和反向参数(匹配排序),并重命名为:

例如:

>>> import itertools
>>> print freq_sorted(itertools.chain.from_iterable(data))
[1, 5, 4, 13, 3, 2, 6, 7, 8, 9, 10, 12, 14]
>>> print freq_sorted(itertools.chain.from_iterable(data), include_freq=True)
# (slightly reformatted)
[(1, 5),
 (5, 4),
 (4, 3), (13, 3),
 (3, 2),
 (2, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1), (12, 1), (14, 1)]
试试这个:

def rank(*lists):
    d = dict()
    for lst in lists:
        for e in lst:
            if e in d: d[e] += 1
            else: d[e] = 1
    return [j[1] for j in sorted([(d[i],i) for i in d], reverse=True)]
用法示例:

a = [1,2,3,4]
b = [4,5,6,7]
c = [4,1,8,9]

print rank(a,b,c)

您可以使用任意数量的列表作为输入

组合已发布的两个想法:

from itertools import chain
from collections import defaultdict

def frequency(*lists):
    counter = defaultdict(int)
    for x in chain(*lists):
        counter[x] += 1
    return [key for (key, value) in 
        sorted(counter.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)]
注:

  • 在Python2.7中,可以使用
    计数器
    而不是
    defaultdict(int)
  • 此版本将任意数量的列表作为其参数;前导的星号表示它们都将被压缩到一个元组中。如果要传入包含所有列表的单个列表,请省略前导星号
  • 如果列表包含不可损坏的类型,则此操作将中断

  • 您可以计算每个元素的出现次数(直方图),然后按其排序:

    def histogram(enumerable):
      result = {}
      for x in enumerable:
        result.setdefault(x, 0)
        result[x] += 1
      return result
    
    lists = [ [1,2,3,4], [4,5,6,7], ... ]
    
    from itertools import chain
    
    h = histogram(chain(*lists))
    ranked = sorted(set(chain(*lists)), key = lambda x : h[x], reverse = True)
    
    请尝试以下代码:

    def elementFreq(myList):
        #myList is the list of lists
        from collections import Counter
        tmp = []
        for i in myList: tmp += i        
        return(Counter(tmp))
    

    注意:你的列表应该是可散列的类型

    好的ol'O(n**2),啊,我多么想念你。他没有说他想让它变快。这只是简单而已。没错,但O(n^2)的问题是,从“不快”到“慢得无法忍受”的跃迁非常容易。啊。。好。。。速度越快,ofc越好。您在列表链上迭代了两次。如果对柱状图进行排序,只需迭代一次。(另外,你不需要建立一个集合,因为你已经建立了。)@Robert-你是对的,但效率不是唯一的问题。我发现使用直方图的关键点令人困惑——当然,如果这是一个瓶颈,那么当然,我会毫不犹豫。我无法决定哪种解决方案最快。2对于s=O(n**2),但如何使其更快:/我不知道。你的是唯一一个(除了我的,但我复制了你的)应用第二排序顺序的,这是一个很好的方法。两个for循环并不是这些答案中的一些O(n^2)的原因,而这一个不是。在链表中的每个项目上调用count(x)使它们成为O(n^2)。proxylittle:n是
    列表中每个列表长度的总和
    意味着我的嵌套for循环仍然只有O(n),或者“原始数据中的每个项目只处理一次”(粗略简化,严格来说不是真的,但O(2n)仍然是O(n))。此外,排序是O(m logm),最终列表理解是O(m)(其中m是唯一项的数量),因此整个函数是O(n logn)(m不能大于n)。这就是说,“最快”的解决方案仍然取决于它的具体实现方式和输入的特征,但算法复杂性取决于你如何概括它。
    def histogram(enumerable):
      result = {}
      for x in enumerable:
        result.setdefault(x, 0)
        result[x] += 1
      return result
    
    lists = [ [1,2,3,4], [4,5,6,7], ... ]
    
    from itertools import chain
    
    h = histogram(chain(*lists))
    ranked = sorted(set(chain(*lists)), key = lambda x : h[x], reverse = True)
    
    def elementFreq(myList):
        #myList is the list of lists
        from collections import Counter
        tmp = []
        for i in myList: tmp += i        
        return(Counter(tmp))