简体   繁体   English

使用 Python 中的 maxheap 从列表列表创建字典

[英]Create dictionary from a list of lists by using maxheap in Python

What I know is that creating a maxheap in Python is below: The syntax of heapq.heappush(heap, value)我所知道的是在 Python 中创建一个 maxheap 如下: heapq.heappush(heap, value)的语法

li = [5, 7, 9, 1, 3]

maxheap = [-val for val in li]
heapq.heapify(maxheap)

heapq.heappush(maxheap, -10)         
print('maxheap = ', maxheap)       # [-10, -7, -9, -1, -3, -5]

I found a famous interview question and one of its solution.我发现了一个著名的面试问题及其解决方案之一。

"Given a list of the scores of different students, items, where items[i] = [IDi, scorei] represents one score from a student with IDi, calculate each student's top five average. Return the answer as an array of pairs result, where result[j] = [IDj, topFiveAveragej] represents the student with IDj and their top five average. Sort result by IDj in increasing order. A student's top five average is calculated by taking the sum of their top five scores and dividing it by 5 using integer division." “给定一个不同学生、项目的分数列表,其中 items[i] = [IDi, scorei] 表示来自具有 IDi 的学生的一个分数,计算每个学生的前五名平均值。将答案作为一对结果数组返回,其中 result[j] = [IDj, topFiveAveragej] 表示 IDj 的学生及其前五名的平均成绩。按 IDj 升序排列结果。学生的前五名平均成绩的计算方法是将他们的前五名成绩之和除以5 使用 integer 划分。

I saw one of solutions using maxheap and a part of it is below.我看到了一个使用 maxheap 的解决方案,其中一部分如下。

# items = [[1,91],[1,92],[2,93],[2,97],[1,60],[2,77],[1,65],[1,87],[1,100],[2,100],[2,76]]

def highFive(self, items):
    seen = defaultdict(list)
    
    for s_id, score in items:
        heapq.heappush(seen[s_id], -score)
    
    # output seen is {1: [-100, -91, -92, -65, -87, -60], 2: [-100, -97, -77, -93, -76]})
    print("seen = ", seen) 
    ...

This short code is mysterious for me (I'm a Java Dev. and started learning Python recently and my question is not about the algorithm of this solution ).这个短代码对我来说很神秘(我是 Java 开发人员,最近开始学习 Python,我的问题不是关于这个解决方案的算法)。

I know how to create a maxhep for a given integer list and how to create dictionary using defaultdict respectively, but don't understand how this short code doing altogether without even writing some codes which are used when create a dictionary and heap?我知道如何为给定的 integer 列表创建一个 maxhep 以及如何分别使用 defaultdict 创建字典,但不明白这个短代码是如何完全完成的,甚至没有编写一些在创建字典和堆时使用的代码?

First, this code doesn't even write heapq.heapify(seen) to create maxheap.首先,这段代码甚至没有写heapq.heapify(seen)来创建 maxheap。 Simply create default empty dictionary seen, and then looping input items and directly heapq.heappush(seen[s_id], -score)只需创建默认的空字典 seen,然后循环输入项并直接heapq.heappush(seen[s_id], -score)

Second, I printed out seen[s_id] in each iteration.其次,我在每次迭代中打印出seen[s_id] How come dictionary is created after seen[s_id] even without append() method like seen[s_id].append(score) ?即使没有像seen[s_id].append(score)这样的append()方法,为什么在seen[s_id]之后创建字典?

for s_id, score in items:
    id_ = seen[s_id]
    print("\nseen[{0}] = {1}".format(s_id, id_))

    heapq.heappush(id_, -score)         
    ...

output: 
seen[1] = []

seen[1] = [-91]

seen[2] = []

seen[2] = [-93]

seen[1] = [-92, -91]

seen[2] = [-97, -93]

seen[1] = [-92, -91, -60]

seen[1] = [-92, -91, -60, -65]

seen[1] = [-92, -91, -60, -65, -87]

seen[2] = [-97, -93, -77]

seen[2] = [-100, -97, -77, -93]

First, this code doesn't even write heapq.heapify(seen) to create maxheap.首先,这段代码甚至没有写 heapq.heapify(seen) 来创建 maxheap。 Simply create default empty dictionary seen, and then looping input items and directly heapq.heappush(seen[s_id], -score)只需创建默认的空字典 seen,然后循环输入项并直接 heapq.heappush(seen[s_id], -score)

heapq.heapify(myList) changes the order of the elements in the list myList so that it satisfies the properties of a heap. heapq.heapify(myList)更改列表myList中元素的顺序,使其满足堆的属性。 However, if myList is an empty list, then this operation is not needed.但是,如果myList是一个空列表,则不需要此操作。 The empty list already satisfies the properties of a heap.空列表已经满足堆的属性。

Since seen is a defaultdict and not just a regular dict , an entry for seen[s_id] is created automatically, and initialised to an empty list, if this entry doesn't exist already.由于seen是一个defaultdict而不仅仅是一个常规dict ,如果该条目不存在,则自动创建一个seen[s_id]的条目,并初始化为一个空列表。

Second, I printed out seen[s_id] in each iteration.其次,我在每次迭代中打印出 seen[s_id]。 How come dictionary is created after seen[s_id] even without append() method like seen[s_id].append(score)?即使没有像 seen[s_id].append(score) 这样的 append() 方法,为什么会在 seen[s_id] 之后创建字典?

Note that heapq.heappush(seen[s_id], score) and seen[s_id].append(score) are almost equivalent.注意heapq.heappush(seen[s_id], score)seen[s_id].append(score)几乎是等价的。 The only difference is that append adds the element at the end of the list, whereas heapq.heappush adds the element at some position so that the list still satisfies the properties of a heap.唯一的区别是append在列表末尾添加元素,而heapq.heappush在某些 position 中添加元素,因此列表仍然满足堆的属性。

As an illustration, the three following codes produce the same result:作为说明,以下三个代码产生相同的结果:

li = [5, 7, 9, 1, 3]

maxheap = [-val for val in li]
heapq.heapify(maxheap)
li = [5, 7, 9, 1, 3]

maxheap = []
for val in li:
  maxheap.append(-val)
heapq.heapify(maxheap)
li = [5, 7, 9, 1, 3]

maxheap = []
for val in li:
  heapq.heappush(maxheap, -val)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM