在Python中按计数对多个列表的元素进行排序
我想根据它们在每个列表中出现的频率对多个列表进行排序。例如: 列表1=1,2,3,4在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([
列表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)]
注:
计数器
而不是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))