根据枚举迭代或索引列表

时间:2019-09-16 00:51:22

标签: python python-3.x list enums enumeration

我有一个小的枚举列表,其中包含4个元素(class Type(Enum): One,Two,Three,Four),我想知道是否有一种方法可以将枚举与全局列表相关联(List = [Type(0),Type(1),Type(2),Type(3)]。

我知道我可以使用语法List[ Type.Two.value ]访问此列表。但我希望有一种简单的方法来丢掉.value。这不是打字问题-我不介意输入长的描述性变量名。但是列表和枚举是直接相关的/关联的,因此,如果列表将枚举视为迭代器,那将是更好的选择。有没有简单的方法可以做到这一点?

我正在Blender的环境中工作,构建一个附加组件,如果有什么不同的话。我对Python也完全陌生-大约一个星期大,因此,如果有的话,不要忽略明显的地方。

在有任何相似之处的情况下,我对C / C ++非常熟悉。我非常热衷于创建数据库列表并以某种方式关联迭代器类型,从而避免使用与其关联的索引类型名以外的任何方式访问列表(因此,您不会犯类似Cars[my_boat_index]的错误)< / p>

我感谢任何建议!

3 个答案:

答案 0 :(得分:0)

您似乎正在通过将索引的类型限制为特定类型(例如Enum)来限制对列表的访问。

尽管我认为这不是一个好主意,但您绝对可以做到:

from enum import Enum


class MyEnum(Enum):
    ZERO = 0
    ONE = 1
    TWO = 2


class MyList(list):
    def __getitem__(self, item):
        assert isinstance(item, MyEnum)
        return super().__getitem__(item.value)


ml = MyList([1, 2, 3])
print(ml[MyEnum.ONE])
print(ml[1])  # error here

为什么要限制对列表的访问与列表索引的默认类型(即int)不同?

如果您要具有特定的属性,为什么不定义一个类,或者如果要通过特定的值建立索引,为什么不使用字典呢?

也许您应该提供一些有关您实际希望做的事情的信息-Python不是C / C ++,它可能具有某些完全有效的方式来做您想做的事情,而不必模拟C / C ++的工作代替。

如果您不希望限制,而只是要进行迭代(这似乎与问题所指出的不同):

for my_value in MyEnum:
    print(ml[my_value])

如果您对限制仅访问该类型的索引不感兴趣,则可以省略assert语句。

答案 1 :(得分:0)

从文档https://docs.python.org/3/library/enum.html Enumerations support iteration, in definition order开始,您可以遍历它们以构建列表,例如:

from enum import Enum

class Numbers(Enum):
    ONE = 1
    TWO = 2
    THREE = 3

assert [Number.value for Number in Numbers]  == [1,2,3]


答案 2 :(得分:0)

Enum转换为列表很简单:

list(Type)
# [<Type.ONE: 1>, <Type.TWO: 2>, <Type.THREE: 3>, <Type.FOUR: 4>]

使用Type个成员作为索引来访问列表要稍微复杂一些:

  • 默认情况下,成员值从1开始
  • 但是容器索引从0开始
  • 并且成员没有__index____int__方法

简单的解决方案有两个方面:

  • 使用IntEnum代替Enum
  • 0开始计数

所以:

class Type(IntEnum):
    ZERO = 0
    ONE = 1
    TWO = 2
    THREE = 3

IntEnum成员可以在int所在的任何地方使用,因此它们可以很好地用作索引值。

更复杂的解决方案是使用常规Enum,添加所需的方法,并在返回值时减去1:

class Type(Enum):
    ONE = 1
    TWO = 2
    THREE = 3
    FOUR = 4

    def __index__(self):
        return self.value - 1

    def __int__(self):
        return self.value - 1

即使您添加了__index____int__方法,您仍然应该只是从零开始计数,而不是进行减法运算,因为这将在以后使用时引起更多问题Python的工作方式。