0

I have an object class that I use as a key into a python dictionary.

from dataclasses import dataclass


@dataclass
class CompWord:
    c: str
    length: int

    def __hash__(self):
        return hash(self.c)

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


_ = lambda: defaultdict(_)
d = _()
for compword1 in [CompWord('a', 1), CompWord('b', 2)]:
    key = d[compword1]
    for compword2 in [CompWord('c', 1), CompWord('d', 2)]:
        key = key[compword2]

at this point, d is

CompWord(c='a', length=1)
        CompWord(c='c', length=1)
                CompWord(c='d', length=2)
CompWord(c='b', length=2)
        CompWord(c='c', length=1)
                CompWord(c='d', length=2)

I want to update the key in this dictionary if I come across it again only if the length of CompWord is greater than length of key that is already in the dictionary. For example, CompWord(a, 4) > CompWord(a, 1), so I want to update this key with CompWord(a, 4), while also preserving the nested dictionaries under CompWord(a, 1).

Expected output after I update CompWord(a, 1) to Compword(a, 4)

c_word = CompWord('a', 4)
if c_word in d:
    # update d[c_word] with new key CompWord(c_word.length, <old length 1>)
CompWord(c='a', length=4)
        CompWord(c='c', length=1)
                CompWord(c='d', length=2)
CompWord(c='b', length=2)
        CompWord(c='c', length=1)
                CompWord(c='d', length=2)

I need to able to reference the length of the old key above which is 1, but I am not sure how I get access to it.

0

1 Answer 1

2

You've edited your post a bunch since I started writing my answer, and I don't really feel like reading through your post again...

I'd suggest implementing __lt__ and using max():

@dataclass
class CompWord:
    c: str
    length: int
    def __hash__(self):
        return hash(self.c)

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

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

Now accumulate keys to replace:

keys_to_replace = []
for key in d:
    if key == c_word:
        keys_to_replace.append((key, max(key, c_word)))

Now replace keys:

for old_key, new_key in keys_to_replace:
    d[new_key] = d.pop(old_key)

Also, I'd recommend returning self.c == other.c in your __eq__ as that is more explicit.

EDIT:

I suggest implementing a recursive key_replacer() function if you want to drill down into a deeply nested dictionary, as your edits suggest.

I also think it might not be a good idea to __hash__ and __eq__ on only one of the values of your dataclass. That seems like a recipe for headaches during debugging.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.