Mailing List Archive

Converting a string to a tuple
Here is a basic problem that is causing me much stress:

I have a string a = '(1, "abc\\def", 2)' that I would like to convert to a
tuple.

I have tried eval(), but it interprets the backslashes.
Converting a string to a tuple [ In reply to ]
Bruce Huzyk writes:
> Here is a basic problem that is causing me much stress:
>
> I have a string a = '(1, "abc\\def", 2)' that I would like to convert to a
> tuple.
>
> I have tried eval(), but it interprets the backslashes.

The cheapest thing to do is this:

import string
def str_to_tup(s):
return eval(string.replace(s, '\\', '\\\\'))

If you're concerned about safety (the "eval" could be evaluating any
Python code, possibly a hazard if the string is coming from user
input) then you don't want to use eval at all, you need to actually
process the string, looking for commas, quotes, backslashes, etc. If
you need to do this, you may find some parser generator/lexical
analyzer tools already in existence, if you look around python.org
Converting a string to a tuple [ In reply to ]
Charles G Waldman wrote:
> If you're concerned about safety (the "eval" could be evaluating any
> Python code, possibly a hazard if the string is coming from user
> input) then you don't want to use eval at all.

try:

result = eval(string, {"__builtins__": {}})

or:

import rexec
r = rexec.RExec()
result = r.r_eval(string)

</F>
Converting a string to a tuple [ In reply to ]
I will now take this opportunity to revise my original post.
I wish to convert a string to a tuple.
My sample string should have been:
s = '(1, "abc\\tef", 2)'
instead of:
s = '(1, "abc\\def", 2)'

The problem is that the \\t part of the string gets expanded to a \011

Only the eval(string.replace(s, '\\', '\\\\')) seems to do the job. Any
comments?

sample code:
>>> s = '(1, "abc\\tef", 2)'
>>> eval(s)
(1, 'abc\011ef', 2)

s = '(1, "abc\\tef", 2)'
>>> eval(string.replace(s, '\\', '\\\\'))
(1, 'abc\\tef', 2)


>>> s = '(1, "abc\\tef", 2)'
>>> eval(s, {"__builtins__": {}})
(1, 'abc\011ef', 2)


>>> s = '(1, "abc\\tef", 2)'
>>> r = rexec.RExec()
>>> s = '(1, "abc\\tef", 2)'
>>> r = rexec.RExec()
>>> r.r_eval(s)
(1, 'abc\011ef', 2)



Fredrik Lundh <fredrik@pythonware.com> wrote in article
<00f501be857f$ff636f40$f29b12c2@pythonware.com>...
> Charles G Waldman wrote:
> > If you're concerned about safety (the "eval" could be evaluating any
> > Python code, possibly a hazard if the string is coming from user
> > input) then you don't want to use eval at all.
>
> try:
>
> result = eval(string, {"__builtins__": {}})
>
> or:
>
> import rexec
> r = rexec.RExec()
> result = r.r_eval(string)
>
> </F>
>
>
Converting a string to a tuple [ In reply to ]
Bruce Huzyk wrote:
> I will now take this opportunity to revise my original post.
> I wish to convert a string to a tuple.
> My sample string should have been:
> s = '(1, "abc\\tef", 2)'
> instead of:
> s = '(1, "abc\\def", 2)'

if that's Python source code, your string
actually contains:

(1, "abc\tef", 2)

since \\ is Python's string representation
for a single backslash (that is, \\ in the
source code becomes \ in the actual
string).

and \t is an alias for \011 (a tab).

try printing it (using print) to see what
I mean.

but I doubt that this is the real problem --
if you have these strings in Python source
code, you could as well use your editor
to remove the quotes, right?

so if you get the data from a file or any
other external source, the plain eval
solutions work as they should. for
simple data types like this,

v == eval(repr(v))

is always true.

</F>
Converting a string to a tuple [ In reply to ]
> > since \\ is Python's string representation
> > for a single backslash (that is, \\ in the
> > source code becomes \ in the actual
> > string).
>
> > and \t is an alias for \011 (a tab).
>
> No it isn't.

of course it is. when used in Python's string representation,
which was what I was talking about. please read the entire
message before following up on pieces of it.

> The problem arises because of the second evaluation. Either use
> string.replace to double backslashes in the string, prefix the string
> with an "r", or don't use eval.

argh! if you have the string in source code, just remove the
outer quotes. converting strings to tuples has never been
easier. but I suspect Bruce was looking for something else,
and that he was tricked by Python's string syntax and repr.
it has happened to many good programmers before, as can
be seen in the c.l.py archives.

> I'd avoid eval...

why? it's there, it works, and it can be used in a safe way,
as shown in earlier posts. and converting strings to tuples
is kinda hard without it...

</F>
Converting a string to a tuple [ In reply to ]
First let me thank everyone for their help.

Let me take a step back and try to describe my problem with a little more
detail with the disclaimer that I am a little new to Python (but not
programming, BTW I couldn't find the PEWBIE module) and that I am
more of a newsgroup reader then writer so please excuse the fact that this
is my third post.


I will list my solution and ask the question: Is this the way that you
would
implement this?
Any side effects?


E:\PYTHON>type c:\batch\script1.py
import string

fp = open("c:\\test.txt", "r")
s = fp.readline()
s = s[2:]
a = {}
a['1'] = eval(string.replace(s, '\\', '\\\\'))
print type (a['1'])
filename, offset = a['1']
print filename, offset
fp.close

E:\PYTHON>python c:\batch\script1.py
<type 'tuple'>
c:\a\test.txt 1932

E:\PYTHON>type c:\test.txt
:R("c:\a\test.txt",1932)

E:\PYTHON>