Python heapq 模块,对象上的 heapify 方法

发布于 2024-10-01 15:56:51 字数 127 浏览 6 评论 0原文

因为我试图在我正在制作的程序中提高效率,所以我想我应该使用 python 中内置的 heapq 模块,但是我的一些对象具有多个属性,例如名称和编号。有没有办法使用 heapify 方法根据某个属性来堆化我的对象?我在文档中没有看到任何内容。

Since I'm trying to be efficient in this program I'm making, I thought I'd use the built in heapq module in python, but some of my objects have multiple attributes, like name and number. Is there a way to use the heapify method to heapify my objects based on a certain attribute? I don't see anything in the documentation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山人契 2024-10-08 15:56:51

在我发布之后,我想你可以在使用 heapify 之前根据所需的属性创建一个对象列表,这将花费 O(n) 线性时间。这不会影响 heapify 或其他 heapq 方法的运行时。

Right after I posted, I figured you could make a list of the objects by the attribute needed before using heapify which would take O(n) linear time. This wouldn't affect the runtime of heapify or other heapq methods.

偏闹i 2024-10-08 15:56:51

@vsekhar 和@所有其他人都想知道已接受的答案。

假设:

class SomeObject():
    def __init__(self,name, number):
        self.name = name
        self.number = number

a_list = []
obj_1 = SomeObject("tim", 12)
obj_2 = SomeObject("tom", 13)

现在,不是创建一个仅将对象作为元素的堆:

heapq.heappush(a_list, obj_1)
heapq.heappush(a_list, obj_2)

您实际上想要创建一个包含 2 个值的元组作为堆元素的堆 - 这个想法是将要排序的属性作为该属性的第一个值元组和对象(如前所述)作为元组的第二个元素:

# Sort by 'number'.
heapq.heappush(a_list, (obj_1.number, obj_1))
heapq.heappush(a_list, (obj_2.number, obj_2))

堆将元组的第一个值视为排序依据的值。

堆元素可以是元组。这对于在跟踪的主记录旁边分配比较值(例如任务优先级)非常有用:


另一个选项可能是使比较与您的自定义类一起工作 - 可以实现此操作,以便对象本身可以用作堆元素(如在第一个例子中)。

class SomeObject():
    def __init__(self,name, number):
        self.name = name
        self.number = number
    def __eq__(self, obj): 
        return self.number == obj.number 
    def __lt__(self, obj): 
        return self.number < obj.number 
    def __hash__(self): 
        return hash(self.number)

这样您就可以创建仅将对象作为元素的堆:

heapq.heappush(a_list, obj_1)
heapq.heappush(a_list, obj_2)

@vsekhar and @ all the others wondering about the accepted answer.

Assumption:

class SomeObject():
    def __init__(self,name, number):
        self.name = name
        self.number = number

a_list = []
obj_1 = SomeObject("tim", 12)
obj_2 = SomeObject("tom", 13)

Now, instead of creating a heap with the objects only as elements:

heapq.heappush(a_list, obj_1)
heapq.heappush(a_list, obj_2)

you actually want to create the heap with a tuple of 2 values as heap elements - The idea is to have the attribute you want to sort with as first value of the tuple and the object (as before) as the second element of the tuple:

# Sort by 'number'.
heapq.heappush(a_list, (obj_1.number, obj_1))
heapq.heappush(a_list, (obj_2.number, obj_2))

The heap considers this first value of the tuple as the value to sort by.

  • In case the element pushed to the heap is not of a simple data type like int or str, the underlying implementation needs to know how to compare elements.
  • If the element is an iterable the first element is considered to contain the sort value.
  • Have a look at the examples here: https://docs.python.org/3/library/heapq.html#basic-examples (search for tuple)

Heap elements can be tuples. This is useful for assigning comparison values (such as task priorities) alongside the main record being tracked:


Another option might be to make comparison work with your custom class - This can be implemented so the object itself can be used as the heap element (as in the first example).

class SomeObject():
    def __init__(self,name, number):
        self.name = name
        self.number = number
    def __eq__(self, obj): 
        return self.number == obj.number 
    def __lt__(self, obj): 
        return self.number < obj.number 
    def __hash__(self): 
        return hash(self.number)

This way you can create the heap with the objects only as elements:

heapq.heappush(a_list, obj_1)
heapq.heappush(a_list, obj_2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文