Comment obtenir toutes les valeurs de la classe enum python?

141

J'utilise la bibliothèque Enum4 pour créer une classe enum comme suit:

class Color(Enum):
    RED = 1
    BLUE = 2

Je veux imprimer [1, 2]sous forme de liste quelque part. Comment puis-je atteindre cet objectif?

user1159517
la source

Réponses:

49

Vous pouvez utiliser IntEnum :

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2


print(int(Color.RED))   # prints 1

Pour obtenir la liste des entiers:

enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]
Marcin
la source
Vous utilisez un tiers. Mais il dit aussi qu'il a un intenum
Marcin
Comment imprimer comme [(1, 'RED'), (2, 'BLUE')]
user1159517
Qu'en est-il de ceci: a = [(int(v), str(v)) for v in Color]et puis print(a).
Marcin
34
Que diriez-vous de ceci:[(color.value, color.name) for color in Color]
vlad-ardelean
2
Le commentaire de @ vlad-ardelean est le meilleur et le plus pythonique. C'est l'utilisation idiomatique du type Enum, élégant et éminemment lisible
Dusktreader
432

Vous pouvez faire ce qui suit:

[e.value for e in Color]
Ozgur
la source
1
@ user2340939 Cela renvoie la liste des énumérations, pas la liste des valeurs. Si cela vous convient, vous pouvez aussi bien utiliserlist(Color)
endolith
1
Cela devrait être marqué comme la bonne réponse.
SKYFALL26
22

Pour utiliser Enum avec n'importe quel type de valeur, essayez ceci:
Mise à jour avec quelques améliorations ... Merci @Jeff, par votre astuce!

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 'GREEN'
    BLUE = ('blue', '#0000ff')

    @staticmethod
    def list():
        return list(map(lambda c: c.value, Color))

print(Color.list())

À la suite:

[1, 'GREEN', ('blue', '#0000ff')]
Jeff
la source
6
J'utiliserais @classmethod au lieu de @ staticmethod
ISONecroMAn
1
@ISONecroMAn je suppose @classmethodqu'il faudrait créer une instance de Colorclasse. C'est pourquoi staticmethodsemble être le bon choix ici.
Leonid Dashko
@LeonidDashko pas du tout. Voyez ma réponse.
blueFast le
@LeonidDashko @dangoonfast est correct. Vous pouvez utiliser @classmethodet utiliser à la return list(map(lambda c: c.value, cls))place.
Riptyde4
18

Sur la base de la réponse de @Jeff, refactorisé pour utiliser un classmethodafin que vous puissiez réutiliser le même code pour n'importe laquelle de vos énumérations:

from enum import Enum

class ExtendedEnum(Enum):

    @classmethod
    def list(cls):
        return list(map(lambda c: c.value, cls))

class OperationType(ExtendedEnum):
    CREATE = 'CREATE'
    STATUS = 'STATUS'
    EXPAND = 'EXPAND'
    DELETE = 'DELETE'

print(OperationType.list())

Produit:

['CREATE', 'STATUS', 'EXPAND', 'DELETE']
blueFast
la source
7

class enum.Enumest une classe qui résout tous vos besoins d'énumération, il vous suffit donc d'en hériter et d'ajouter vos propres champs. Ensuite, tout ce que vous avez à faire est d'appeler simplement ses attributs: name& value:

from enum import Enum

class Letter(Enum):
   A = 1
   B = 2
   C = 3

print({i.name: i.value for i in Letter})
# prints {'A': 1, 'B': 2, 'C': 3}
Meysam Azad
la source
6

Donc, le Enuma un __members__dict. La solution proposée par @ozgur est vraiment la meilleure, mais vous pouvez le faire, ce qui fait la même chose, avec plus de travail

[color.value for color_name, color in Color.__members__.items()]

Le __members__dictionnaire pourrait être utile si vous vouliez y insérer des éléments de manière dynamique ... dans une situation folle.

[EDIT] Apparemment, ce __members__n'est pas un dictionnaire, mais un proxy de carte. Ce qui signifie que vous ne pouvez pas facilement y ajouter d'éléments.

Vous pouvez cependant faire des trucs bizarres comme MyEnum.__dict__['_member_map_']['new_key'] = 'new_value', et ensuite vous pouvez utiliser la nouvelle clé comme MyEnum.new_key.... mais ce n'est qu'un détail d'implémentation, et ne devrait pas être joué avec. La magie noire est payée avec d'énormes coûts de maintenance.

vlad-ardelean
la source
Juste une barre latérale: des éléments peuvent-ils être ajoutés __members__? Ce serait une manière intéressante d'autoriser les extensions , créant ainsi de nouveaux Enummembres. ... btw, voté pour avoir apporté un nouvel attribut ( pour moi ) à la table.
IAbstract
@IAbstract: Non, c'est interdit. Si quelqu'un trouve un moyen d'ajouter / de soustraire des membres après la création de Enum, il cassera probablement cet Enum.
Ethan Furman
@IAbstract: ajouter de nouveaux membres après coup n'est généralement pas une bonne idée. Si vous le souhaitez vraiment, consultez cette réponse .
Ethan Furman
1

Utilisez _member_names_pour un résultat rapide et facile s'il ne s'agit que des noms, c'est-à-dire

Color._member_names_

En outre, vous avez _member_map_qui renvoie un dictionnaire ordonné des éléments. Cette fonction renvoie a collections.OrderedDict, donc vous avez Color._member_names_.items()et Color._member_names_.values()pour jouer avec. Par exemple

return list(map(lambda x: x.value, Color._member_map_.values()))

renverra toutes les valeurs valides de Color

EliuX
la source
-1

vous pouvez utiliser la fonction iter ():

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2
l=[]
for i in iter(Color):
    l.append(i.value)
print(l)
Ali Shekari
la source