3

In python heapq if you are putting in objects, how can u use a lambda to specify its key? Like heapq.heappush(Q, v, key=lambda x: f(x)).

Thanks

omega
  • 40,311
  • 81
  • 251
  • 474
  • umm, wasn't this question already answered [here](http://stackoverflow.com/a/28016978/1426065)? – MattDMo Jan 19 '15 at 03:29

2 Answers2

7

You can't. Or rather, you can't specify it as a lambda. You can however make a heap of tuples, heapq.heappush(Q, (key(v), v)) and heapq.heappop(Q)[1].

U2EF1
  • 12,907
  • 3
  • 35
  • 37
  • 1
    Note that if `v` has no order, `key(v)` must return a unique number. Because if two `key(v)` are equal, heapq will try to order `v` and it will crash. See [this example](https://leetcode.com/problems/merge-k-sorted-lists/discuss/500972/Python-heapq-70-Runtime-98-Memory). – Ferran Maylinch Feb 07 '20 at 11:26
1

Elaborating on my comment, I'd say that U2EF1's solution is valid if f(v) will always return unique values, or if v can be ordered (you could also setup ordering, like in this example).

I made these classes to make it easier to use heapq, and to allow lambdas for sorting.

In general you could do add a unique number to overcome that limitation:

heapq.heappush(Q, create_item(v, f))
(key, v) = heapq.heappop()

# f is your desired function/lambda
# unique_value() generates a different value each time (e.g. a counter)
def create_item(v, f):
    key = (f(v), unique_value())
    return (key, v)

It's a shame there's no way to send a function to heapq... :/

Ferran Maylinch
  • 10,919
  • 16
  • 85
  • 100