2

How can I do the following in a more efficient python friendly way?

first_team= re.sub("Northern", "N", first_team)
first_team=re.sub("Western", "W", first_team)
first_team=re.sub("Southern", "S", first_team)
first_team=re.sub("Eastern", "E", first_team)

4 Answers 4

4

Use a for-loop:

for direction in ('Northern', 'Western', 'Southern', 'Eastern'):
    first_team = first_team.replace(direction, direction[0])

There's no need to use re.sub here for dealing with such simple replacement :), str.replace is perfectly fine.

Sign up to request clarification or add additional context in comments.

1 Comment

Your code is fine for this specific example. If OP really wants just this, good. But for a general replacement, one would need to specify a mapping as other poster proposed.
3

I would use .replace and do:

opts = [ ("Northern", "N"), ("Western", "W"), ("Southern", "S"), ("Eastern", "E") ]

for opt in opts:
    first_team = first_team.replace(opt[0], opt[1])

Comments

1

Your re.sub()s can be rewritten into a one-liner using lambda as a second argument:

>>> import re
>>> s = "Northern Western Southern Eastern" 
>>> re.sub("(Northern|Western|Southern|Eastern)", lambda x: x.group(1)[0] , s)
'N W S E'

Note that the replacement is too simple for doing it via regex.

But, what if, for example, you want to replace strings like north, North too:

>>> s = "Northern North north Western Southern Eastern" 
>>> re.sub("([Nn]orth(ern)?|[Ww]est(ern)?|[Ss]outh(ern)?|[Ee]ast(ern)?)", lambda x: x.group(1)[0].upper(), s)
'N N N W S E'

That's there you may need to use re.sub.


Also, you may use replace() with a reduce():

>>> opts = {"Northern": "N", "Western": "W", "Southern": "S", "Eastern": "E"}
>>> reduce(lambda k, v: k.replace(*v), opts.iteritems(), s)
'N W S E'

This is basically the same as applying replace() in a for loop but written in a functional programming style.

Comments

0

I'd like to show you my own solution. At the first view, it might be complicated, but after defining the "basics", application is really simple

First, I define a mapping as a list of tuples:

our_mapping = [("Northern", "N"),
           ("Western", "W"),
           ("Southern", "S"),
           ("Eastern", "E")]

Now comes the beef: I define a factory function that recursively creates an All-In-One replacement function:

def replacer_factory(mapping):
    if len(mapping) < 1:
        return lambda x: x
    original, replacement = mapping[0]
    return lambda x: replacer_factory(mapping[1:])(x.replace(original, replacement))

Now I can create a replacement function with my mapping:

our_replacer = replacer_factory(our_mapping)

And then application is really easy:

>>> in_ = "Northern Western Southern Eastern"
>>> out_ = our_replacer(in_)
>>> print in_
Northern Western Southern Eastern
>>> print out_
N W S E

I really like that we don't need any parameters to call our_replacer, all the mapping-logic has been hidden inside of it. One can now easily define arbitrary replacers and use them.

Here the code as a whole:

our_mapping = [("Northern", "N"),
           ("Western", "W"),
           ("Southern", "S"),
           ("Eastern", "E")]

def replacer_factory(mapping):
    if len(mapping) < 1:
        return lambda x: x
    original, replacement = mapping[0]
    return lambda x: replacer_factory(mapping[1:])(x.replace(original, replacement))

our_replacer = replacer_factory(our_mapping)

in_ = "Northern Western Southern Eastern"
out_ = our_replacer(in_)

print in_
print out_

I agree that this can be considered "advanced" - so if you are a newbie and "just want it to work", stick to jabaldonedos answer.

1 Comment

Doing this recursively is just un-necessary, inefficient and overly complicated :(

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.