查找string enum成员索引的有效方法



我有一个常量Enum类,看起来像这样:

class Animals(Enum):
Dog= 'dog'
Cat= 'cat'
Chicken = 'chicken'
Horse = 'horse'

我需要找到一个简单而有效的方法来查找枚举成员之一的索引。所以我想出了以下的联机:

list(Animals).index(Animals.Chicken)

输出:

2

问题是,解析到一个列表并再次搜索它是不够有效的,我不能改变常数。感觉应该有一个简单的解决方案,我错过了。

您有几个选择:

  • 使用索引值作为EnumIntEnum的值
class Animals(Enum):
Dog= 0
Cat= 1
Chicken = 2
Horse = 3
Animals.Chicken.value #returns 2
  • 如果你想保持文字描述太,然后子类Enum,并添加所需的属性(见行星的例子在文档):
class Animals(Enum):
Dog = ('dog',0)
Cat = ('cat',1)
Chicken = ('chicken',2)
Horse = ('horse',3)
def __init__(self, textval, idx):
self.textval = textval
self.idx = idx
Animals.Chicken.value #returns ('chicken', 2)
Animals.Chicken.textval #returns 'chicken'
Animals.Chicken.idx #returns 2

由于Enum成员名不以数字开头,您可以简单地使Enum子类的_member_map_属性(存储成员名到值映射的字典)也存储索引数到值映射。

这可以通过将Enum的元类EnumMeta子类化,并在原始__new__方法返回的类对象中为_member_map_属性的所有对应值添加索引作为新键来完成:

from enum import Enum, EnumMeta
class IndexableEnumType(EnumMeta):
def __new__(metacls, cls, bases, classdict, **kwargs):
enum_class = super().__new__(metacls, cls, bases, classdict, **kwargs)
for i, v in enumerate(list(enum_class._member_map_.values())):
enum_class._member_map_[i] = v
return enum_class

:

class Animals(Enum, metaclass=IndexableEnumType):
Dog= 'dog'
Cat= 'cat'
Chicken = 'chicken'
Horse = 'horse'
print(Animals[2])
print(Animals['Chicken'])
print(Animals.Chicken)

将输出:

Animals.Chicken
Animals.Chicken
Animals.Chicken

由于字典查找的平均时间复杂度为0 (1),因此这比当前调用list.index的解决方案要有效得多,后者的时间复杂度为0 (n)

演示:https://replit.com/@blhsing/AdventurousVapidCollaborativesoftware

最新更新