This question already has an answer here:
-
*
/questions/26577621/get-next-enumerator-constant-property
/questions/26577621/get-next-enumerator-constant-property
2 answers
Answers
Note that you can provide succ and pred methods inside an Enum class:
class Sequential(Enum): A = 1 B = 2 C = 4 D = 8 E = 16 def succ(self): v = self.value * 2 if v > 16: raise ValueError( Enumeration ended ) return Sequential(v) def pred(self): v = self.value // 2 if v == 0: raise ValueError( Enumeration ended ) return Sequential(v)
Used as:
>>> import myenums >>> myenums.Sequential.B.succ() <Sequential.C: 4> >>> myenums.Sequential.B.succ().succ() <Sequential.D: 8> >>> myenums.Sequential.B.succ().succ().pred() <Sequential.C: 4>
Obviously this is efficient only if you actually have a simple way to compute the values from an item to the next or preceding one, which may not always be the case.
If you want a general efficient solution at the cost of adding some space, you can build the mappings of the successor and predecessor functions. You have to add these as attributes after the creation of the class (since Enum messes up attributes) so you can use a decorator to do that:
def add_succ_and_pred_maps(cls): succ_map = {} pred_map = {} cur = None nxt = None for val in cls.__members__.values(): if cur is None: cur = val elif nxt is None: nxt = val if cur is not None and nxt is not None: succ_map[cur] = nxt pred_map[nxt] = cur cur = nxt nxt = None cls._succ_map = succ_map cls._pred_map = pred_map def succ(self): return self._succ_map[self] def pred(self): return self._pred_map[self] cls.succ = succ cls.pred = pred return cls @add_succ_and_pred_maps class MyEnum(Enum): A = 0 B = 2 C = 8 D = 18
Used as:
>>> myenums.MyEnum.A.succ() <MyEnum.B: 2> >>> myenums.MyEnum.B.succ() <MyEnum.C: 8> >>> myenums.MyEnum.B.succ().pred() <MyEnum.B: 2> >>> myenums.MyEnum._succ_map {<MyEnum.A: 0>: <MyEnum.B: 2>, <MyEnum.C: 8>: <MyEnum.D: 18>, <MyEnum.B: 2>: <MyEnum.C: 8>}
you probably want a custom exception instead of KeyError but you get the idea.
There probably is a way to integrate the last step using metaclasses, but it s notstraightforward for the simple fact thatEnums are implemented using metaclasses and it s not trivial to compose metaclasses.
Source
License : cc by-sa 3.0
http://stackoverflow.com/questions/38007103/how-can-i-elegantly-find-the-next-and-previous-value-in-a-python-enum