Question

I have a file with a lot of lines like this

f(a, b)
f(abc, def)
f(a, f(u, i))
...

and I was asked to write a program in Python that would translate the strings into the following format:

a+b
abc+def
a+(u+i)
...

Rule: f(a, b) -> a+b

The approach I am following right now uses eval functions:

def f(a, b):
    return "({0} + {1})".format(a,b)

eval("f(f('b','a'),'c')")

which returns

'((b + a) + c)'

However, as you can see, I need to put the letters as strings so that the eval function does not throw me a NameError when I run it.

Is there any way that will allow me to get the same behavior out of the eval function but without declaring the letters as strings?

Était-ce utile?

La solution

eval is overkill here. this is just a simple string processing exercise:

  • replace the first 'f(' and the last ')' with ''
  • replace all remaining 'f(' with '('
  • replace all ', ' with '+'

and you're done.

this assumes that the only time the characters 'f(' appear next to each other is when it's supposed to represent a call to function f.

Autres conseils

Yes, you can. The key is to use a mapping which returns the string as a key when it is missing.

>>> class Mdict(dict):
...     def __missing__(self, k):
...         return k
... 
>>> eval('foo + bar', Mdict())
'foobar'

Of course, the general caveats about eval apply -- Please don't use it unless you trust the input completely.

You could use the shlex module to give yourself a nice token stack and then parse it as a sort of push down automaton.

>>> import shlex
>>> def parsef(tokens):
    ftok = tokens.get_token()       # there's no point to naming these tokens
    oparentok = tokens.get_token()  # unless you want to assert correct syntax
    lefttok = tokens.get_token()
    if 'f' == lefttok:
        tokens.push_token(lefttok)
        lefttok = "("+parsef(tokens)+")"
    commatok = tokens.get_token()
    righttok = tokens.get_token()
    if 'f' == righttok:
        tokens.push_token(righttok)
        righttok = "("+parsef(tokens)+")"
    cparentok = tokens.get_token()
    return lefttok+"+"+righttok
>>> def parseline(line):
    return parsef(shlex.shlex(line.strip()))
>>> parseline('f(a, b)')
'a+b'
>>> parseline('f(abc, def)')
'abc+def'
>>> parseline('f(a, f(u, i))')
'a+(u+i)'

Note that this assumes you are getting correct syntax.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top