简体   繁体   English

将字典插入堆Python

[英]Inserting dictionary to heap Python

I'm trying to build a heap with (key, value) so the key is a number and the value is a dictionary. 我正在尝试使用(键,值)构建一个堆,因此键是一个数字,值是一个字典。

import heapq
heap = []
dic = {'val_1': 'number_1', 'val_2': 'number_2', 'val_3': 'number_3'}
insetToHeap = (2,dic)
heapq.heappush(heap, insetToHeap)

The code crashes on heappush . 代码在heappush崩溃了。 The element probably not in the right format. 元素可能不是正确的格式。

EDIT: 编辑:

The error is: 错误是:

TypeError: unorderable types: dict() < dict() TypeError:unorderable类型:dict()<dict()

What is the right way to insert to heap the (number, dic) elements? 插入(number,dic)元素的正确方法是什么?

Thanks. 谢谢。

Dictionaries can't be ordered, so you need to create something that can keep the dictionary but doesn't use it in comparisons. 字典无法排序,因此您需要创建一些可以保留字典但不在比较中使用字典的字典。

Tuples are not a good choice because every element in them might be compared. 元组不是一个好选择,因为它们中的每个元素都可能被比较。 For example if the first element (your key ) is equal then the second item is compared: 例如,如果第一个元素(您的key )相等,则比较第二个元素:

>>> (1, {'a': 1}) < (1, {'a': 2})
TypeError: unorderable types: dict() < dict()

Or with heap : 或者用heap

>>> heap = []
>>> heapq.heappush(heap, (2, {'a': 1}))
>>> heapq.heappush(heap, (2, {'b': 2}))
TypeError: unorderable types: dict() < dict()

If the key is garantueed to be unequal then there's no problem because the second item won't be compared. 如果key被限制为不相等,则没有问题,因为第二项不会被比较。

In case you just want some storage for the dict you could simply create a class that stores (key, value) but only ever compares the key : 如果您只想为dict存储一些存储空间,您可以简单地创建一个存储(key, value)的类,但只能比较key

from functools import total_ordering

@total_ordering
class KeyDict(object):
    def __init__(self, key, dct):
        self.key = key
        self.dct = dct

    def __lt__(self, other):
        return self.key < other.key

    def __eq__(self, other):
        return self.key == other.key

    def __repr__(self):
        return '{0.__class__.__name__}(key={0.key}, dct={0.dct})'.format(self)

Insert these into your heap and this will garantuee that the dict won't be compared: 将这些插入到您的heap ,这将证明dict不会被比较:

>>> import heapq
>>> heap = []
>>> heapq.heappush(heap, KeyDict(2, {'a': 1}))
>>> heapq.heappush(heap, KeyDict(2, {'b': 2}))
>>> heap
[KeyDict(key=2, dct={'a': 1}), KeyDict(key=2, dct={'b': 2})]

An alternative is to use 3 tuples using a counter as second element that garantuees the comparison won't go to the dict: 另一种方法是使用一个计数器作为第二个元素来使用3个元组,这些元素可以使比较不会转到dict:

>>> from itertools import count
>>> cnt = count()
>>> heap = []
>>> heapq.heappush(heap, (2, next(cnt), {'a': 1}))
>>> heapq.heappush(heap, (2, next(cnt), {'b': 2}))
>>> heap
[(2, 0, {'a': 1}), (2, 1, {'b': 2})]

dict instances cannot be compared in Python 3: 在Python 3中无法比较dict实例:

>>> {'a': 9} < {'a': 10}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'

which means neither can your tuples if the first elements are equal: 这意味着如果第一个元素相等,你的元组也不会:

>>> (2, {'a': 9}) < (3, {'a': 10})
True
>>> (2, {'a': 9}) < (2, {'a': 10})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>>

You need to ensure that the dict s themselves never need to be compared. 你需要确保dict本身永远不需要进行比较。

So I did a bit of testing and even though you didn't show your full code it would seem that your code is pushing to the heap more than one dict . 所以我做了一些测试,即使你没有显示完整的代码,你的代码似乎也会向堆中推送多个dict

>>> heapq.heappush(heap, (0,dic))
>>> heapq.heappush(heap, (0,dic2))
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unorderable types: dict() < dict()

Your heap is comparing the dictionaries because the first item of the list has been compared and so it proceeds to compare the next item, instead you need to do something like: 你的堆正在比较字典,因为列表的第一项已被比较,所以它继续比较下一个项目,而你需要做类似的事情:

>>> heapq.heappush(heap, (0,dic))
>>> heapq.heappush(heap, (1,dic))
>>> show_tree(heap)

(0, {'val_1': 'number_1', 'val_2': 'number_2', 'val_3': 'number_3'})
(1, {'val_1': 'number_1', 'val_2': 'number_2', 'val_3': 'number_3'})
------------------------------------

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM