My Input is:
input = ['(var1, )', '(var2,var3)']
Expected Output is:
output = [('var1', ), ('var2','var3')]
Iterating over input and using eval
/literal_eval
on the tuple-strings is not possible:
>>> eval('(var1, )')
>>> NameError: name 'var1' is not defined
How can I convert an item such as '(var1, )'
to a tuple where the inner objects are treated as strings instead of variables?
Is there a simpler way than writing a parser or using regex?
For each occurrence of a variable, eval
searches the symbol table for the name of the variable. It's possible to provide a custom mapping that will return the key name for every missing key:
class FakeNamespace(dict):
def __missing__(self, key):
return key
Example:
In [38]: eval('(var1,)', FakeNamespace())
Out[38]: ('var1',)
In [39]: eval('(var2, var3)', FakeNamespace())
Out[39]: ('var2', 'var3')
Note: eval
copies current globals to the submitted globals
dictionary, if it doesn't have __builtins__
. That means that the expression will have access to built-in functions, exceptions and constants, as well as variables in your namespace. You can try to solve this by passing FakeNamespace(__builtins__=<None or some other value>)
instead of just FakeNamespace()
, but it won't make eval
100% safe (Python eval: is it still dangerous if I disable builtins and attribute access?)
Try this:
tuples = [tuple(filter(None, t.strip('()').strip().split(','))) for t in input]
For example:
In [16]: tuples = [tuple(filter(None, t.strip('()').strip().split(','))) for t in input]
In [17]: tuples
Out[17]: [('var1',), ('var2', 'var3')]
We're iterating through our list of tuple strings, and for each one, removing the ()
s, then splitting our string into a list by the ,
, and then converting our list back into a tuple. We use filter()
to remove empty elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With