I have a bytearray that I need to use as a key to a dictionary. Ideally I’d like to do this without doing a copy of memory the size of the bytearray. Is there anyway to do this?
Basically,
b = some bytearray
d[byte(b)] = x
Is there any faster way to do this? byte(b) is an O(len(bytearray)) operation which is undesirable.
Any hash algorithm that actually does its job correctly will use O(len(b)) time. So the answer to “is there any faster way to do this” is no.
If your actual concern is memory usage, then you could, in principle, add a
__hash__method to a subclass of bytearray. But that’s a pretty bad idea. Look what happens:So the same object could hash to two different spots in the dictionary, which isn’t supposed to happen. And it gets worse:
Ok, so far, so good. The values are equal, so there should be only one item in the dictionary. Everything is working as expected. Now let’s see what happens when we change
hb1:See how even though
hb2didn’t change at all, it created a new key-value pair in the dictionary this time?Every time I passed a key to
d, that key was equal to'abcd'. But because the value of the first key changed after being added to the dictionary, Python couldn’t tell that the value of the new key was the same as the old key had been when it was added. Now there are two key-value pairs in the dictionary, when there should be only one.This is only one of many ways that using mutable values as keys can lead to unpredictable and very wrong behavior. Just convert the
bytearrayto an immutable type, or work with immutable types in the first place.And for the inquisitive: sure,
buffercaches the first hash, but that doesn’t help at all. There are only two key values, so this should generate only two dict entries:But it generates three: