views:

117

answers:

6

In Python I have four strings that include the formatting of a list:

line1 ="['a.b.c','b.c.a','c.d.e']"
line2 ="['def','efg']"
line3 ="['f']"
line4 ="['g']"

How do I merge them all so I get a valid Python list such as:

SumLine = ['a.b.c','b.c.a','c.d.e','def','efg','f','g']
+11  A: 
import ast

line1 ="['a.b.c','b.c.a','c.d.e']"
line2 ="['def','efg']"
line3 ="['f']"
line4 ="['g']"

SumLine = []

for x in (line1, line2, line3, line4):
  SumLine.extend(ast.literal_eval(x))

print SumLine

Don't use the built-in eval unless you have preternatural trust in the strings you're evaluating; ast.literal_eval, while limited to simple constants, is totally safe and therefore, most often, way preferable.

Alex Martelli
Note that the ast module is only available in Python 2.6 and higher.
Zach Hirsch
@Zach, yep, 2.5 has `_ast` but that's lower level and thus harder to work with.
Alex Martelli
+1  A: 

Try eval:

>>> line1 ="['a.b.c','b.c.a','c.d.e']"
>>> line2 ="['def','efg']"
>>> line3 ="['f']"
>>> line4 ="['g']"
>>> eval(line1) + eval(line2) + eval(line3) + eval(line4)
['a.b.c', 'b.c.a', 'c.d.e', 'def', 'efg', 'f', 'g']

But be careful, because eval can be dangerous. Don't use it on input that you receive from the user and haven't validated.

Zach Hirsch
A: 

you need to eval them first and then you could sum the results. But I wonder how do you get this strings in the first place?

SilentGhost
+1  A: 

The quick and dirty way is to use eval:

SumLine = eval(line1) + eval(line2) + eval(line3) + eval(line4)

But dont do this if you are getting these strings from someone else (ie user input)

truppo
+1  A: 

The simple way is to concetenate the strings to an expression that can be evaulated to give the required result:

line1 ="['a.b.c','b.c.a','c.d.e']"
line2 ="['def','efg']"
line3 ="['f']"
line4 ="['g']"
lines = [line1, line2, line3, line4]

print eval('+'.join(lines))

However this is unsafe if you can't trust your input, so if you're using Python 2.6 or higher you should use the safe eval function ast.literal_eval in the ast module, although this doesn't work with the '+' trick so you will have to iterate over each element instead.

Mark Byers
literal_eval doesn't work with +, only literals.
Zach Hirsch
@Zach, yep, this gives `ValueError: malformed string`. Wouldn't it be nice if people minimally tried answers out before accepting them?-)
Alex Martelli
I guess he chose the plain 'eval' version. I removed the incorrect code for the literal_eval.
Mark Byers
+1  A: 

Where did you get these strings? Anything short of a real parser will be fragile. Below is what I would recommed, if I had not seen Alex Martelli's brilliant answer before!

You may parse them as JSON arrays, but JSON wants to read double-quoted strings, not single quotes. This introduces fragility to the method, but still much preferable to eval() which is unsafe.

import json
line1 ="['a.b.c','b.c.a','c.d.e']"
json.loads(line1.replace("'", '"'))

The result is a parsed list like [u'a.b.c', u'b.c.a', u'c.d.e'], you may than go on to join the parsed lists.

kaizer.se
I hope you don't have any escaped single-quotes in the middle of those strings, or you'll be affecting the content too... bug!
Peter Hansen