如何在保留列表的同时通过某个索引从矩阵中 heappush 列表?
How do I heappush lists from a matrix by a certain index while preserving the list?
假设我有一个列表:
l1 = [[1, 3], [3, 2], [2, 1]]
我想将 l1
中的每个项目推送到二进制堆,'memory' 但在二进制堆中按 each_item[-1]
排序。
我试过:heapq.heappush(_heap, item=itemgetter(-1))
和使用匿名函数的等价物,但我得到:
TypeError: heappush() takes no keyword arguments
一个选项是围绕 heapq
函数制作小型包装器以 prepend/extract 排序值 to/from 项目以一致的方式:
def heappush(h, item, key=lambda x: x):
heapq.heappush(h, (key(item), item))
def heappop(h):
return heapq.heappop(h)[1]
def heapify(h, key=lambda x: x):
for idx, item in enumerate(h):
h[idx] = (key(item), item)
heapq.heapify(h)
正在使用您的样本进行测试:
l1 = [[1, 3], [3, 2], [2, 1]]
h = []
for item in l1:
heappush(h, item, key=itemgetter(-1))
while h:
print(heappop(h))
打印:
[2, 1]
[3, 2]
[1, 3]
请注意,您可以使用 h=l1; heapify(h, key=itemgetter(-1))
,这应该比单独 heappush
每个项目更快。
您可以将堆中的条目存储为 3 元素元组,包括最后一个元素、条目计数和实际项目。这样,项目将按照它们的最后一个值进行排序,条目计数确保排序稳定性(即,最后一个元素相同的两个项目按照它们添加的顺序返回):
>>> import heapq
>>> heap = []
>>> l1 = [[1, 3], [3, 2], [2, 1]]
>>> for count, item in enumerate(l1):
... heapq.heappush(heap, (item[-1], count, item))
...
>>> while heap:
... print(heapq.heappop(heap)[-1])
...
[2, 1]
[3, 2]
[1, 3]
我喜欢 Eugene 的解决方案,但如果经常使用这个特殊的元组,可以定义一个自定义对象来实现这一点,如下所示:
from heapq import heappush, heappop
class MyTupleHeapObj(object):
def __init__(self,val): self.val = val
def __lt__(self,other): return self.val[-1] < other.val[-1]
def __eq__(self,other): return self.val == other.val
def __str__(self): return str(self.val)
h = []
for item in [[1, 3], [3, 2], [2, 1]]:
heappush(h, MyTupleHeapObj(item))
while h:
print heappop(h)
打印以下内容:
[2, 1]
[3, 2]
[1, 3]
假设我有一个列表:
l1 = [[1, 3], [3, 2], [2, 1]]
我想将 l1
中的每个项目推送到二进制堆,'memory' 但在二进制堆中按 each_item[-1]
排序。
我试过:heapq.heappush(_heap, item=itemgetter(-1))
和使用匿名函数的等价物,但我得到:
TypeError: heappush() takes no keyword arguments
一个选项是围绕 heapq
函数制作小型包装器以 prepend/extract 排序值 to/from 项目以一致的方式:
def heappush(h, item, key=lambda x: x):
heapq.heappush(h, (key(item), item))
def heappop(h):
return heapq.heappop(h)[1]
def heapify(h, key=lambda x: x):
for idx, item in enumerate(h):
h[idx] = (key(item), item)
heapq.heapify(h)
正在使用您的样本进行测试:
l1 = [[1, 3], [3, 2], [2, 1]]
h = []
for item in l1:
heappush(h, item, key=itemgetter(-1))
while h:
print(heappop(h))
打印:
[2, 1]
[3, 2]
[1, 3]
请注意,您可以使用 h=l1; heapify(h, key=itemgetter(-1))
,这应该比单独 heappush
每个项目更快。
您可以将堆中的条目存储为 3 元素元组,包括最后一个元素、条目计数和实际项目。这样,项目将按照它们的最后一个值进行排序,条目计数确保排序稳定性(即,最后一个元素相同的两个项目按照它们添加的顺序返回):
>>> import heapq
>>> heap = []
>>> l1 = [[1, 3], [3, 2], [2, 1]]
>>> for count, item in enumerate(l1):
... heapq.heappush(heap, (item[-1], count, item))
...
>>> while heap:
... print(heapq.heappop(heap)[-1])
...
[2, 1]
[3, 2]
[1, 3]
我喜欢 Eugene 的解决方案,但如果经常使用这个特殊的元组,可以定义一个自定义对象来实现这一点,如下所示:
from heapq import heappush, heappop
class MyTupleHeapObj(object):
def __init__(self,val): self.val = val
def __lt__(self,other): return self.val[-1] < other.val[-1]
def __eq__(self,other): return self.val == other.val
def __str__(self): return str(self.val)
h = []
for item in [[1, 3], [3, 2], [2, 1]]:
heappush(h, MyTupleHeapObj(item))
while h:
print heappop(h)
打印以下内容:
[2, 1]
[3, 2]
[1, 3]