convert string to list

J

Jochen Hub

Hi,

I am a real beginner in Python and I was wondering if there is a way to
convert a string (which contains a list) to a "real" list.

I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

Thanks you,
Jochen
 
D

Diez B. Roggisch

Jochen said:
I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

Why don't you give the args standalone

thescript.py "A" "B" "C"

and do this:

thelist = sys.argv[1:]
 
C

Cliff Wells

Hi,

I am a real beginner in Python and I was wondering if there is a way to
convert a string (which contains a list) to a "real" list.

I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

You can use eval for this. Better, you could simply pass your list as a
series of arguments from bash:

#!/bin/bash
myscript.py A B C


#!/usr/bin/python
import sys
thelist = sys.argv[1:]

Regards,
Cliff
 
J

Jochen Hub

thescript.py ["A","B","C"]


You can use eval for this. Better, you could simply pass your list as a
series of arguments from bash:

I tried with eval...simply using

thelist=eval(argv[1])

it didn't work :-(, I got the error message

File "./findCenter.py", line 64, in ?
print eval(sys.argv[1])
#!/bin/bash
myscript.py A B C

The problem is that I want to pass one or two lists to the script, so it
should be able to distinguish between

thescript ["A","B"] ["C","D",E"]
thescript ["A","B","C"] ["D",E"]
thescript ["A","B","C","D",E"]
 
W

Wolfram Kraus

Jochen said:
Hi,

I am a real beginner in Python and I was wondering if there is a way to
convert a string (which contains a list) to a "real" list.

I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

Thanks you,
Jochen
If you are sure that the list always looks that way:
>>> l = '["A","B","C"] '
>>> l[1:-2].replace('"','').split(',')
['A', 'B', 'C']


HTH,
Wolfram
 
W

Wolfram Kraus

Wolfram said:
Jochen said:
Hi,

I am a real beginner in Python and I was wondering if there is a way
to convert a string (which contains a list) to a "real" list.

I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

Thanks you,
Jochen

If you are sure that the list always looks that way:
l = '["A","B","C"] '
l[1:-2].replace('"','').split(',')
['A', 'B', 'C']


HTH,
Wolfram
Damn, I knew there must be something wrong with the -2 (too much work
today??):
>>> l = '["A","B","C"]'
>>> l[1:-1].replace('"','').split(',')
['A', 'B', 'C']

Or try the other solution with multiple arguments (better way IMHO)

Wolfram
 
C

Cliff Wells

#!/bin/bash
myscript.py A B C

The problem is that I want to pass one or two lists to the script, so it
should be able to distinguish between

thescript ["A","B"] ["C","D",E"]
thescript ["A","B","C"] ["D",E"]
thescript ["A","B","C","D",E"]

Okay, after considering several alternatives, it occurs to me that,
depending upon the scope of this script, eval might not be a bad way to
go. There are two main questions you have to ask yourself when deciding
if eval is safe:

1. Where will the arguments come from? If you are hardwiring them into
the bash script (and the script is properly secured) then I don't think
there's a problem. If they come from an untrusted source (network data,
etc), then you should by no means use eval.

2. Is there any chance this script will be run suid? I know Linux
doesn't allow suid scripts, but that doesn't prevent the script from
being run by a suid executable and thus gaining privileges.

If you feel secure about those two things, then I would say go ahead
with the eval-based solution, since it is clearly the simplest:

#!/bin/bash
script.py "['a', 'b', 'c']" "['d', 'e', 'f']"



#!/usr/bin/python
import sys

arglist = []
for arg in sys.argv[1:]:
arglist.append(eval(arg))

print arglist


Regards,
Cliff
 
J

Jeff Shannon

Jochen said:
I tried with eval...simply using

thelist=eval(argv[1])

it didn't work :-(, I got the error message

File "./findCenter.py", line 64, in ?
print eval(sys.argv[1])
#!/bin/bash
myscript.py A B C

The problem here is with shell quoting more than anything else. In
order for eval() to work, the sys.argv[1] must look like a normal Python
list literal once your script gets hold of it. That means that firstly,
you need to get bash to pass everything after your script name (or at
least, everything that's part of the list) as a single argument, and
secondly, you need to have quoting right so that the contents of the
list will be interpreted as strings, not variable names. Try something
like:

myscript.py "['A', 'B', 'C']"

However, I'm not sure how much manipulation of those quotes bash will do
before it passes the arguments on to Python -- read man bash for
specifics, I think it's in there somewhere, but it might not be pretty.

Also be aware that there's some serious risks here; consider the
following --

myscript.py "__import__('os'); os.system('rm -rf /*')"

.... which will actually attempt to delete your entire filesystem, or as
much of it as the current user has access to. Be very careful about
accepting data to feed to eval().

On the other hand, if you use the other suggestions of simply passing
arguments in bare (as you're trying to do) and using sys.argv[1:] as
your argument list, then you'll be fine... except that you'll have a
hard time passing in two separate lists. I'm not sure that trying to
accept two lists is really the best idea, but you could perhaps use some
sentinel value to indicate where you want lists broken...

Jeff Shannon
Technician/Programmer
Credit International
 
M

Michael Foord

Jochen Hub said:
Hi,

I am a real beginner in Python and I was wondering if there is a way to
convert a string (which contains a list) to a "real" list.

I need this since I would like to give a list as an argument to my
Python script from the bash:

#!/usr/bin/python
import sys
argument1 = sys.argv[1]
thelist = ???(argument1)

and then call the script from the bash like this

thescript.py ["A","B","C"]

Thanks you,
Jochen


Other posters have mentioned difficulties with what the shell will do
to your command line. If you can get it as a single string - I've
written a module that will turn a string like that back into a list. I
use it for reading lists from config files. It will properly handle
the quotes etc.....

It's called listwuote and you can find it at
http://www.voidspace.org.uk/atlantibots/pythonutils.html#listquote

Regards,

Fuzzy
 
J

Josef Meile

Hi,
#!/bin/bash
script.py "['a', 'b', 'c']" "['d', 'e', 'f']"



#!/usr/bin/python
import sys

arglist = []
for arg in sys.argv[1:]:
arglist.append(eval(arg))

print arglist
Why not just:

script.py "a, b, c" "d, e, f"

Then:
> arglist = []
> for arg in sys.argv[1:]:
> arglist.append(arg.split(','))

Better than eval.

Regards,
Josef
 
C

Cliff Wells

Why not just:

script.py "a, b, c" "d, e, f"

Then:
arglist = []
for arg in sys.argv[1:]:
arglist.append(arg.split(','))

Better than eval.

A basic problem is that the OP gave no indication of what would really
be passed as the lists (well, I'm assuming that his examples of ['A',
'B', 'C'] were contrived for simplicity). Without knowing this, then
it's impossible to know if a character such as ',' might be contained in
the data. If it is then splitting on ',' is going to fail. A better
approach might be to pass the info as valid CSV data and use the csv
module to evaluate it:

#!/bin/bash
python bar.py '"a","b","c"' '"d","e","f"'


#!/usr/bin/python
import sys, csv
from StringIO import StringIO

for arg in sys.argv[1:]:
reader = csv.reader(StringIO(arg))
for row in reader:
print row


Regards,
Cliff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,209
Messages
2,571,088
Members
47,686
Latest member
scamivo

Latest Threads

Top