繁体   English   中英

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

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

我所知道的是在 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]

我发现了一个著名的面试问题及其解决方案之一。

“给定一个不同学生、项目的分数列表,其中 items[i] = [IDi, scorei] 表示来自具有 IDi 的学生的一个分数,计算每个学生的前五名平均值。将答案作为一对结果数组返回,其中 result[j] = [IDj, topFiveAveragej] 表示 IDj 的学生及其前五名的平均成绩。按 IDj 升序排列结果。学生的前五名平均成绩的计算方法是将他们的前五名成绩之和除以5 使用 integer 划分。

我看到了一个使用 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) 
    ...

这个短代码对我来说很神秘(我是 Java 开发人员,最近开始学习 Python,我的问题不是关于这个解决方案的算法)。

我知道如何为给定的 integer 列表创建一个 maxhep 以及如何分别使用 defaultdict 创建字典,但不明白这个短代码是如何完全完成的,甚至没有编写一些在创建字典和堆时使用的代码?

首先,这段代码甚至没有写heapq.heapify(seen)来创建 maxheap。 只需创建默认的空字典 seen,然后循环输入项并直接heapq.heappush(seen[s_id], -score)

其次,我在每次迭代中打印出seen[s_id] 即使没有像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]

首先,这段代码甚至没有写 heapq.heapify(seen) 来创建 maxheap。 只需创建默认的空字典 seen,然后循环输入项并直接 heapq.heappush(seen[s_id], -score)

heapq.heapify(myList)更改列表myList中元素的顺序,使其满足堆的属性。 但是,如果myList是一个空列表,则不需要此操作。 空列表已经满足堆的属性。

由于seen是一个defaultdict而不仅仅是一个常规dict ,如果该条目不存在,则自动创建一个seen[s_id]的条目,并初始化为一个空列表。

其次,我在每次迭代中打印出 seen[s_id]。 即使没有像 seen[s_id].append(score) 这样的 append() 方法,为什么会在 seen[s_id] 之后创建字典?

注意heapq.heappush(seen[s_id], score)seen[s_id].append(score)几乎是等价的。 唯一的区别是append在列表末尾添加元素,而heapq.heappush在某些 position 中添加元素,因此列表仍然满足堆的属性。

作为说明,以下三个代码产生相同的结果:

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