2

Is there a way to index a dict using an enum?

e.g. I have the following Enum and dict:

class STATUS(Enum):
    ACTIVE = "active"

d = { "active": 1 }

I'd like to add the appropriate logic to the class STATUS in order to get the following result:

d[STATUS.ACTIVE]
# returns 1

I understand that the type of STATUS.ACTIVE is not a string.. But is there a way around other than declaring the dict using STATUS.ACTIVE instead of "active"?

Also: looking for a solution other than adding a class property or .value

alps
  • 93
  • 7

2 Answers2

3

@ElmovanKielmo solution will work, however you can also achieve your desired result by making the STATUS Enum derive from str as well

from enum import Enum


class STATUS(str, Enum):
    ACTIVE = "active"


d = {"active": 1}

print(d[STATUS.ACTIVE])
# prints 1

Please keep in mind, that when inheriting from str, or any other type, the resulting enum members are also that type.

Nelala_
  • 301
  • 2
  • 9
  • Great solve! Thank you @Nelala_ this may be for another post on here (happy to create a new one if folks feel it would be appropriate), but I also have the case where my enum is of the form: class STATUS(Enum): ACTIVE = "active", 1 (so it's a tuple) ... effectively same question, where I want print(d[STATUS.ACTIVE]) to print 1 for the same d – alps Sep 29 '22 at 23:27
  • Same solution as here, but deriving from tuple instead of str | "class STATUS(tuple, Enum):" :) – Nelala_ Sep 29 '22 at 23:35
  • Well, this causes the dict indexing to error out as it expects an str rather than tuple in this new scenario... Any way around? – alps Sep 29 '22 at 23:40
  • Ah, I misunderstood your comment. So you want to return only the first item in the tuple by default? Some hacky solution, like custom dicts would probably work, but I think you'll have a better chance at an answer if you post this as a new question. – Nelala_ Sep 29 '22 at 23:45
  • 1
    @alps: [This solution](https://stackoverflow.com/a/66428177/208880) should work for your secondary question. – Ethan Furman Sep 30 '22 at 15:53
0

You could use your custom dictionary class:

from collections import UserDict
from enum import Enum

class MyDict(UserDict):
    def __getitem__(self, key):
        if isinstance(key, Enum):
            key = key.value
        return super().__getitem__(key)

class STATUS(Enum):
    ACTIVE = "active"

d = MyDict({ "active": 1 })
d[STATUS.ACTIVE]
ElmoVanKielmo
  • 10,907
  • 2
  • 32
  • 46