0

I have a web form that accepts user input for string modifications to be applied to information being passed via a given column in a csv. Because I am attempting to use existing architecture I am applying these modifications to lambda functions. For most of the mods it is fairly straight forward, but for my replace modification I would like to do this dynamically, for example a string I might receive from my form might be:

('you', 'me' / 'this', 'that' / 'do', "don't")

the lambda equivalent I would like to create for passing with this data would be:

func = lambda v: str(v).replace('you', 'me').replace('this', 'that').replace('do', "don't")

I can easily do this by limiting the amount of replaces that can be done and then counting the delimiters ('/' in this case) and creating them individually using if statements and such.
I hate this idea for 2 reasons:

  1. I am effectively limiting my users modification capabilities by putting limits on how many modifications they are allowed to do on a given string
  2. it does not feel pythonic.

I would prefer an approach like this:

func = lambda v: str(v)
for mod in modstring.split(' / '):
    func = func + .replace(mod.split(', ')[0], mod.split(', ')[1])

but I highly doubt such functionality exists... I figure this question is a long-shot but it was worth a try.

3 Answers 3

2

lambdas and regular functions are interchangeable. So, I'd write this as a function returning a function:

def make_replacer(s):
    mods = [mod.split(', ') for mod in s.split(' / ')]
    def replacer(v):
        v = str(v)
        for mod in mods:
            v = v.replace(mod[0], mod[1])
        return v
    return replacer

Example use:

>>> f1 = make_replacer('foo, bar / moo, car')
>>> f2 = make_replacer('foo, dar / moo, ear')
>>> f1('foo$$moo')
'bar$$car'
>>> f2('foo$$moo')
'dar$$ear'
Sign up to request clarification or add additional context in comments.

1 Comment

Worked like a charm! I integrated my other types of modifiers into this one function and after some preliminary testing it looks like it is going to work great! Thanks! I find it interesting that my initial inclination of being able to say v = v.some_additional_function() allows you to append functions onto existing ones was in fact not far off from the truth. Another affirmation that python can be most intuitive language out there. IMHO of course.
2
import re

# I am going to assume that your form input is literally of the form
# """('you', 'me' / 'this', 'that' / 'do', "don't")"""
# so this parses it into
# [("you", "me"), ("this", "that"), ("do", "don't")]
def parse_form_string(s, reg=re.compile("(['\"])(.*?)(\\1)")):
    words = [qw[1] for qw in reg.findall(s)]
    return zip(words[::2], words[1::2])

# we use the input-string to build a function
# which will perform the replacements
def my_replace_fn(form_string):
    pairs = parse_form_string(form_string)
    def fn(s):
        for a,b in pairs:
            s = s.replace(a, b)
        return s
    return fn

# then we can use it like
inp = """("cat", 'dog' / "mouse", "flea" )"""
my_fn = my_replace_fn(inp)

my_fn("my cat has a mouse")   # => "my dog has a flea"

Comments

1

Consider this:

parse_replace = lambda i: i.split(', ') # 'one, two' => [ 'one', 'two' ]

f = lambda v, inputstring: reduce( lambda a,b: a.replace(*parse_replace(b)), v.split(' / '), inputstring )

# So: f('one, derp / three, four', 'onetwothree') # ==> 'derptwofour'

Note: This assumes your input string is actually formatted like: 'one, two / three, four'.

Comments

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.