Search code examples
pythondictionary

Converting between two sets of constants


I have two enums NAME and ALIAS which are guaranteed to have the same number of constants, and I need a way to convert each constant from NAME to its corresponding one from ALIAS, and vice-versa. For example:

def name_to_alias(name):
    if name == Name.PAUL:
        return Alias.STARCHILD
    elif name == Name.GENE:
        return Alias.DEMON
    ...

def alias_to_name(alias):
    if alias == Alias.STARCHILD:
        return Name.PAUL
    elif alias == Alias.DEMON:
        return Name.GENE
    ...

I don't wish to maintain two functions (or dicts) like these. Ideally, I'd have the enum mappings in a single data structure which I can access from both conversion functions.

I'm thinking of something like:

mappings = {
    Name.PAUL: Alias.STARCHILD
    Name.GENE: Alias.DEMON
    ...
}

This would work for converting from Name to Alias, but the opposite may have issues (what happens if I make a copy-paste error and end up with two dict keys with the same value?). Is there an easy and safe way to achieve this?


Solution

  • Considering that could occur that in mappings more than one name could have the same alias a safe function should raise an error, like

    mappings = {
        Name.PAUL: Alias.STARCHILD,
        Name.GENE: Alias.DEMON,
        Name.PETER: Alias.CATMAN,
        Name.ALICE: Alias.DEMON
    }
    
    def alias_to_name(alias):
    #check if the alias is more than once in the mappings and raise an error
        if list(mappings.values()).count(alias) > 1:
            raise ValueError('Alias is not unique', alias, [name for name, a in mappings.items() if a == alias])
        else:
            return [name for name, a in mappings.items() if a == alias]
    

    That will output

    ('Alias is not unique', <Alias.DEMON: 2>, [<Name.GENE: 2>, <Name.ALICE: 4>])