Sunday, September 8, 2013

Converting a Dictionary formatted String to Python Dictionary object

From my github repo: https://github.com/weqaar/gpio


Say you have this in a text file, a String in Dictionary format.

You just can't read it as a Dict object, this will need String to Dict conversion.

SERVER_LIST={mysql:145,queue:144}



#Convert String to Dictionary
gpio_dict = {}
strdict = conf_params.SERVER_DICT.strip("{").strip("}")
for item in strdict.split(','):
key,value = item.split(':')
if gpio_dict.get( key ):
gpio_dict[ key ] += int( value )
else:
gpio_dict[ key ] = int( value )

2 comments:

  1. This snippet should also do the job

    strdict = '{mysql:145,queue:144}'
    d = dict(re.findall('(\w+):(\w+),?', strdict))
    gpio_dict = {k : int(v) for k, v in d.iteritems()}

    Although I recommend doing the following

    Store SERVER_LIST={"mysql":145,"queue":144}
    instead of SERVER_LIST={mysql:145,queue:144}

    that way
    >>> import json
    >>> json.loads('{"mysql":145,"queue":144}')
    {u'queue': 144, u'mysql': 145}

    ReplyDelete
  2. SERVER_LIST is defined in a text file "gpio.conf" under config section "[PINMAP]" parsed using ConfigParser module:

    [PINMAP]
    SERVER_LIST={mysql:145,queue:144}

    This is how we read it in an extern py module:

    class gpio_SysInit (object):
    gpio_conf = "gpio.conf"
    '''Parameters from conf file'''
    SERVER_DICT = None

    """blah blah blah...."""

    def __init__(self):
    self.config_parser()

    def config_parser(self):
    rcp = RawConfigParser()
    if rcp.read(self.gpio_conf) == []:
    return self.ERROR

    '''PINMAP Parameters'''
    self.SERVER_DICT = rcp.get("PINMAP","SERVER_LIST").strip("")

    Lets redefine everything for clarity here:

    runtime.py:
    ---------------
    from ConfigParser import RawConfigParser

    def init_conf():
    gpio_conf = "gpio.conf"
    '''Parameters from conf file'''
    global SERVER_DICT
    SERVER_DICT = None
    rcp = RawConfigParser()
    if rcp.read(gpio_conf) == []:
    print "error in rcp.read()\n"
    return self.ERROR
    SERVER_DICT = rcp.get("PINMAP","SERVER_LIST").strip("")
    print str(SERVER_DICT)


    def main():
    init_conf()
    gpio_dict = {}
    strdict = SERVER_DICT.strip("{").strip("}")
    for item in strdict.split(','):
    key,value = item.split(':')
    if gpio_dict.get( key ):
    gpio_dict[ key ] += int( value )
    else:
    gpio_dict[ key ] = int( value )

    print str(gpio_dict)

    if __name__ == '__main__':
    main()

    gpio.conf:
    --------------
    [PINMAP]
    #NO spaces in SERVER_LIST
    SERVER_LIST={mysql:145,queue:144}


    Executing runtime.py give that on stdout:
    --------------------------------------------------------
    {mysql:145,queue:144}
    {'queue': 144, 'mysql': 145}


    What have so far is a "text string" converted to a python object "dictionary".


    Ofcourse, there might be several ways you could do such a thing, some of 'em as you have mentioned.

    I am an avid fan of "Optimized Code", a die hard fan rather :)

    So if we consider my approach as required i.e. a small memory device:

    Python re is based on PCRE and is NP-Hard, which may lead to exponential matching times O(X^n) whereas the simpler approach I use is linear O(n).


    It requires a bit of work for JSON module to decode the text into object, SERVER_LIST needs to be in the form first '{"mysql":145, "queue":144}', then we may use json.loads(SERVER_LIST).

    json.decode still returns a string, rather a python representation of str instance containing a JSON document; this still requires conversion to a dictionary type object {}


    For the JSON solution, we need to look at the disassembled code using dis.dis and compare both approaches for an optimized runtime.




    ReplyDelete