How to convert string to list without eval or exec

Mike C. Fletcher mcfletch at rogers.com
Tue Mar 9 05:32:04 EST 2004


Oliver Kurz wrote:

>Hello,
>
>could someone give me a solution how to convert a string to a list without using eval or exec?
>
>The string looks like:
>
>'[["abc","abc",["abc","abc"],"abc"],["abc","abc",["abc","abc"],["abc",["abc","abc"]],"abc"],"abc"]'
>
>and should be converted to a list:
>
>[['abc', 'abc', ['abc', 'abc'], 'abc'], ['abc', 'abc', ['abc', 'abc'], ['abc', ['abc', 'abc']], 'abc'], 'abc']
>
>I'm not allowed to use eval or exec.
>  
>
You'd normally use a parser package for this kind of work, here's a 
SimpleParse parser for simple list structures including strings, floats, 
integers and/or hexadecimal-format integers, with support for embedded 
comments and the like as you see in Python:

from simpleparse.parser import Parser
from simpleparse.common import strings, numbers, comments
from simpleparse.dispatchprocessor import *

grammar = r"""
content        := list+
list           := sp,'[',sp, listContents?, sp,']',sp
 >listChild<    := string / float / hex / int / list
 >listContents< := listChild,(sp,',',sp, listChild )*, (sp,',',sp)?
<sp>           := ([ \t\n] / hash_comment)*
"""

parser = Parser( grammar, "content" )

class ListProcessor( DispatchProcessor ):
    string = strings.StringInterpreter()
    int = numbers.IntInterpreter()
    hex = numbers.HexInterpreter()
    float = numbers.FloatInterpreter()
    def list( self, (tag, start, stop, children), buffer ):
        """Get processed children for the children of the list"""
        return dispatchList( self, children, buffer )

if __name__ == "__main__":
    import pprint
    texts = [
        
'[["abc","abc",["abc","abc"],"abc"],["abc","abc",["abc","abc"],["abc",["abc","abc"]],"abc"],"abc"]',
        """[ # a list of some sort
        [ # first child
            2.345, 3,
        ],
        ] [] # end of multi-line list""",
    ]
    for text in texts:
        result = parser.parse( text, processor=ListProcessor() )
        pprint.pprint( result )

Now, you'll notice the return-value is actually a list-of-lists from the 
top-level production.  If you only want to allow one list at the 
top-level, simply specify:

parser = Parser( grammar, "list" )

To use the list production as the top-level production.

SimpleParse is available here:
    http://simpleparse.sourceforge.net/

Of course, for such simple samples, writing your own recursive descent 
parser might be just as easy :) .

Have fun, and good luck,
Mike

_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/






More information about the Python-list mailing list