According to the example from the documentation, you can use tuples, and it will sort by the first element of the tuple:
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
So if you don't want to (or can't?) do a __cmp__ method, you can manually extract your sorting key at push time.
Note that if the first elements in a pair of tuples are equal, further elements will be compared. If this is not what you want, you need to ensure that each first element is unique.
Answer from Jander on Stack OverflowAccording to the example from the documentation, you can use tuples, and it will sort by the first element of the tuple:
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
So if you don't want to (or can't?) do a __cmp__ method, you can manually extract your sorting key at push time.
Note that if the first elements in a pair of tuples are equal, further elements will be compared. If this is not what you want, you need to ensure that each first element is unique.
heapq sorts objects the same way list.sort does, so just define a method __cmp__() within your class definition, which will compare itself to another instance of the same class:
def __cmp__(self, other):
return cmp(self.intAttribute, other.intAttribute)
Works in Python 2.x.
In 3.x use:
def __lt__(self, other):
return self.intAttribute < other.intAttribute
How does heap pop works when popping tuple items?
Confused by heapq's behavior regardring tuples.
Python heapq.heappush for tuple not working as expected - Stack Overflow
How do you perform heapify on a list of tuples
To make a heap based on the first (0 index) element:
import heapq heapq.heapify(A)
If you want to make the heap based on a different element, you'll have to make a wrapper class and define the __cmp__() method.
I've saw that when setting tuple item as heap element, it would get the first value while popping minimum values from heap.
heap = [(1, 10), (2, 99)]
For the above heap, it's obvious that it would pop the element (1, 10) first, since first elemnt of tuple 1 < 2
However, for those tuple elements where first element is same
heap = [(1, 10), (1, 99)]
I've tested some cases, heap would drop the element (1, 10) first, looks like it compares the second element when first element is same for multiples.
Is that the correct logic that heap would compare following values while first element is the same for tuples?
Was doing some leetcode problems when i encountered some weird behavior i can't make sense of.
arr_wtf = [2,7,10] h_wtf = [] for n in set(arr_wtf): heappush(h_wtf, (arr_wtf.count(n)*-1, n*-1)) print(h_wtf) arr_ok = [7,10,9] h_ok = [] for n in set(arr_ok): heappush(h_ok, (arr_ok.count(n)*-1, n*-1)) print(h_ok)
Above is the minimalist version to illustrate whats confusing me.
What it should do is fill the heap with tuples of count and value and order them (thus the multiply by minus one.
h_ok works as expected giving [(-1, -10), (-1, -9), (-1, -7)]
but h_wtf gives [(-1, -10), (-1, -2), (-1, -7)]
Notice the -2 between -10 and -7
In case of a tie heapq should look up the next value inside a tuple.
Shouldn't the order of h_wtf be [(-1, -10), (-1, -7), (-1, -2)] ?
Hope you guys can understand what im trying to describe.
Related leecode problem is:
3318. Find X-Sum of All K-Long Subarrays I
If I have A=[(1,30),(2,10),(3,15),(4,89),(5,60)] How do I use the heapify function on the 1st index of each tuple? In order to get A=[(2,10),(3,15),(1,30),(5,60),(4,89)]
To make a heap based on the first (0 index) element:
import heapq
heapq.heapify(A)
If you want to make the heap based on a different element, you'll have to make a wrapper class and define the __cmp__() method.
u/jpritcha3-14 has the right answer for what you asked. However, are you sure you want heapify and not sorted? Heapify wouldn't give you A=[(2,10),(3,15),(1,30),(5,60),(4,89)], it would give you [(2, 10), (1, 30), (3, 15), (4, 89), (5, 60)]. For what you want, you can run
sorted(A, key=lambda x: x[1])
If you do really want heapify for this very specific purpose, and don't feel like making a wrapper class, one slightly silly workaround would be
A = [(j, i) for i, j in A]
heapify(A)
A = [(j, i) for i, j in A]
or even wrap it in a function
def heap_index_1(arr):
arr = [(j, i) for i, j in arr]
heapify(arr)
arr = [(j, i) for i, j in arr]