1

Let's say I have a list of aliases tied to 5 digit codes available at runtime:

aliasPairs = [(12345,'bob'),(23456,'jon'),(34567,'jack'),(45678,'jill'),(89012,'steph')]

I want to find a terse way to express: replace the id in the line with the matching alias, e.g. :

line = "hey there 12345!"
line = re.sub('\d{5}', value in the aliasPairs which matches the ID, line)
print line

Should output:

hey there bob!

How do Python pros write enumerative expressions in a terse manner?

Thanks and cheers!

3
  • 1
    So each five digit code corresponds to one alias? Consider using a dictionary. Commented Aug 7, 2018 at 18:47
  • @Kevin that would also do, however an extensible data structure doesn't really matter too much because I will only have a max of about 10-15 aliases hard coded. I am more wondering how to do lambdas and the like in Python. Commented Aug 7, 2018 at 18:50
  • 1
    Python doesn't have a built-in function for lookups in an association list, which is why you want a dictionary. dict(aliasPairs) will build the dictionary for you. Commented Aug 7, 2018 at 18:51

2 Answers 2

4

Consider using a dictionary when you have a one-to-one mapping of two categories of data, such as five digit codes and aliases. Then it's easy to access any particular alias, given its code:

import re

aliases = {
    "12345":"bob",
    "23456":"jon",
    "34567":"jack",
    "45678":"jill",
    "89012":"steph"
}

line = "hey there 12345!"
line = re.sub('\d{5}', lambda v: aliases[v.group()], line)
print(line)

Result:

hey there bob!
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, I absolutely love the lambda call.
1

If you will be using these aliases directly in your code (not just referenced from data structures) then an Enum is a good way to go1:

from enum import Enum

class Alias(Enum):
    bob = 12345
    jon = 23456
    jack = 34567
    jill = 45678
    steph = 89012

Then using re would look like:

line = "hey there 12345!"
line = re.sub('\d{5}', lambda v: Alias(int(v.group()).name, line)

You could also add that behavior directly to the Alias Enum with a method:

    @classmethod
    def sub(cls, line):
        return re.sub('\d{5}', lambda v: cls(int(v.group())).name, line)

and in use:

Alias.sub("hey there 12345!")

Of course, "bob" should probably be capitalized, but who wants Alias.Bob all over their code? Best to have the substitution text be separate from the Enum member name, a job more easily accomplished with aenum2:

from aenum import Enum
import re

class Alias(Enum):
    _init_ = 'value text'
    bob = 12345, 'Bob'
    jon = 23456, 'Jon'
    jack = 34567, 'Jack'
    jill = 45678, 'Jill'
    steph = 89012, 'Steph'
    @classmethod
    def sub(cls, line):
        return re.sub('\d{5}', lambda v: cls(int(v.group())).text, line)

Alias.sub('hey there 34567!')

1 See this answer for the standard Enum usage.

2 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

2 Comments

This is a really cool use of the of Enums. Question: the Alias.sub call looks kind of like a static access call to the class Alias, does the init get called the first time I call the Alias.sub method or upon invocation with every call to the 'class'?
@Rice: In Enum classes all the Enum members (aka class instances) are created when the class itself is created; both __new__ and __init__ are invoked at that time. Any future operations that return an Enum member are returning one of the already created members.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.