Python根据接收的输入动态创建一个字符串修改lambda函数

时间:2014-04-04 17:38:12

标签: python lambda

我有一个Web表单,接受用于字符串修改的用户输入,以应用于通过csv中的给定列传递的信息。因为我试图使用现有的架构,所以我将这些修改应用于lambda函数。对于大多数mod来说,它是相当直接的,但对于我的替换修改,我想动态地执行此操作,例如我可能从我的表单中收到的字符串可能是:

('你','我' /'这','' /'做',& #34;不要")

我希望用这个数据传递的lambda等价物是:

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

我可以通过限制可以执行的替换次数,然后计算分隔符(在这种情况下为' /')并使用if语句等单独创建它们来轻松完成此操作。
> 我讨厌这个想法有两个原因:

  1. 我通过限制允许对给定字符串执行的修改来限制用户修改功能
  2. 感觉不到pythonic。
  3. 我更喜欢这样的方法:

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

    但我非常怀疑这种功能是否存在...... 我认为这个问题很长,但值得一试。

3 个答案:

答案 0 :(得分:2)

lambdas和常规函数是可以互换的。所以,我把它写成一个返回函数的函数:

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

使用示例:

>>> f1 = make_replacer('foo, bar / moo, car')
>>> f2 = make_replacer('foo, dar / moo, ear')
>>> f1('foo$$moo')
'bar$$car'
>>> f2('foo$$moo')
'dar$$ear'

答案 1 :(得分: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"

答案 2 :(得分:1)

考虑一下:

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'

注意:这假设您的输入字符串实际上格式为:'one,two / three,four'。