Is there a better way to create a long list of enumeration with auto-numbering starting at 0? The closest that I can find is:
class Color(Enum):
red, green, blue=range(3)
However, the above approach requires knowing the total items in the enumeration beforehand.
If the first enumerator has no initializer, the value of the corresponding constant is zero. An enumerator-definition without an initializer gives the enumerator the value obtained by increasing the value of the previous enumerator by one. So yes, if you do not specify a start value, it will default to 0.
Enumerate with a Different Starting Index So as you know, indices in python start at 0. This means that when you use the enumerate function, the index returned for the first item will be 0.
Rule description. The default value of an uninitialized enumeration, just like other value types, is zero.
To declare an enumerationWrite a declaration that includes a code access level, the Enum keyword, and a valid name, as in the following examples, each of which declares a different Enum . Define the constants in the enumeration.
The documentation provides a recipe for autonumbering that can easily be adapted to start from zero:
class AutoNumber(Enum):
def __new__(cls):
value = len(cls.__members__) # note no + 1
obj = object.__new__(cls)
obj._value_ = value
return obj
Then you can create it with arbitrary members:
class Color(AutoNumber):
red = ()
green = ()
blue = ()
Alternatively, note that the functional API can take an iterable of key-value pairs:
from itertools import count
Color = Enum('Color', zip(['red', 'green', 'blue'], count()))
itertools.count
is basically an open-ended equivalent of range
.
However, the docs also provide the reason for members generally starting with 1
:
The reason for defaulting to
1
as the starting number and not0
is that0
isFalse
in a boolean sense, but enum members all evaluate toTrue
.
Starting from zero may lead to confusing behaviour later on.
As @jonrsharpe already showed, an Enum can be created like this:
Color = Enum('Color', ['RED', 'GREEN', 'BLUE'])
This will be indexed (starting) by 1.
The official documentation states, from Python 3.5:
use the
start
parameter to specify a different starting value
As the documentation states, you can do exactly that:
Color = Enum('Color', ['RED', 'GREEN', 'BLUE'], start=0)
The OP clarified that their motivation is to use the enum value as an array index, which implies consecutive numbering starting from zero.
The documentation states:
The goal of the default [autonumbering] methods is to provide the next int in sequence with the last int provided, but the way it does this is an implementation detail and may change.
Hence it may be wise to define the autonumbering method explicitly, for example:
from enum import IntEnum, auto
class PrimaryColours(IntEnum):
def _generate_next_value_(name, start, count, last_values):
"""generate consecutive automatic numbers starting from zero"""
return count
RED = auto()
GREEN = auto()
BLUE = auto()
This will ensure that the enum
values are assigned consequtive values starting from zero:
print(PrimaryColours.RED.value,
PrimaryColours.GREEN.value,
PrimaryColours.BLUE.value)
> 0 1 2
Note that the value
property can be omitted if the context doesn't require it, e.g.:
orange = (255, 102, 0)
print(orange[PrimaryColours.GREEN])
> 102
If you prefer declaring a class in an old fashioned way, in Python 3.6.4
you can try something like this:
from enum import Enum, auto
class MyEnum(Enum):
FIELD_1 = 0
FIELD_2 = auto()
FIELD_3 = auto()
print(list(MyEnum))
should result in:
>> [<MyEnum.FIELD_1: 0>, <MyEnum.FIELD_2: 1>, <MyEnum.FIELD_3: 2>]
If you don't set FIELD_1
to 0
, then enum property values shall start from 1
.
Just do;
from enum import IntEnum
color = IntEnum('color', ['red', 'green', 'blue'], start=0)
Or if you want to have a class;
class Color (IntEnum):
def __init__(*args, **kwargs):
start = kwargs.pop('start', None)
if start is None:
kwargs['start'] = 0
super().__init__(*args, **kwargs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With