2

I am getting various data types from a config file and adding them to a dictionary. but I am having a problem with lists. I want to take a line with text: alist = [1,2,3,4,5,6,7] and convert into a list of integers. But I am getting

['1', ',', '2', ',', '3', ',', '4', ',', '5', ',', '6', ',', '7'].  

How can I fix this?

Here is config.txt:

firstname="Joe"
lastname="Bloggs"
employeeId=715
type="ios"
push-token="12345"
time-stamp="Mon, 22 Jul 2013 18:45:58 GMT"
api-version="1" 
phone="1010"
level=7
mylist=[1,2,3,4,5,6,7]

Here is my code to parse:

mapper = {}

def massage_type(s):
    if s.startswith('"'):
        return s[1:-1]
    elif s.startswith('['):
        return list(s[1:-1])   #in this case get 'mylist': ['1', ',', '2', ',', '3', ',', '4', ',', '5', ',', '6', ',', '7']
    elif s.startswith('{'):
        return "object"   #todo
    else:
        return int(s)



doc = open('config.txt')
for line in doc:
    line = line.strip()
    tokens = line.split('=')
    if len(tokens) == 2:
        formatted = massage_type(tokens[1])
        mapper[tokens[0]] = formatted

    #check integer list
    mapper["properlist"] = [1,2,3,4,5,6,7]  #this one works

print mapper

Here is my printed output:

{'time-stamp': 'Mon, 22 Jul 2013 18:45:58 GMT', 'mylist': ['1', ',', '2', ',', '3', ',', '4', ',', '5', ',', '6', ',', '7'], 'employeeId': 715, 'firstname': 'Joe', 'level': 7, 'properlist': [1, 2, 3, 4, 5, 6, 7], 'lastname': 'Bloggs', 'phone': '1010', 'push-token': '12345', 'api-version': '1', 'type': 'ios'}

Update.

Thanks for the feedback. I realised that I could also get heterogeneous list so changed list part to:

elif s.startswith('['):
    #check element type
    elements = s[1:-1].split(',')
    tmplist = []           #assemble temp list
    for elem in elements:
        if elem.startswith('"'):
            tmplist.append(elem[1:-1])
        else:
            tmplist.append(int(elem))

    return tmplist

It only handles strings and integers but is good enough for what I need right now.

3

7 Answers 7

2

You need to change the return statement to.

return [int(elem) for elem in s[1:-1].split(',')] # Or map(int, s[1:-1].split(',')) 
Sign up to request clarification or add additional context in comments.

2 Comments

you dont need a lambda in the map
Yeah. Sorry. Fixed it. :)
2

maybe try ast.literal_eval

here is an example:

import ast

str1 = '[1,2,3,4,5]'
ast.literal_eval(str1)

output will be a list like this:

[1,2,3,4,5]

it wont include the commas in the list

Comments

1

You might also consider using ConfigParser (Python 3 example below, Python 2 imports ConfigParser.ConfigParser, I believe):

from configparser import ConfigParser

parser = ConfigParser()
conf_file = os.path.join(dir_it's_located_in, 'config.txt')
parser.read(conf_file)

After that, it's really basic: your whole config file is treated like a dictionary object and all configuration lines are keys in the dictionary:

firstname = parser['firstname']
lastname = parser['lastname']

You can also set up sections in your configuration like so:

[employee info]
email = "[email protected]"
birthday = 10/12/98

And you can reference these in the following way:

birthday = parser["employee info"]["birthday"]

And, as always, there are some great examples in the docs: http://docs.python.org/3.2/library/configparser.html

Comments

0

You can use split():

elif s.startswith('['):
    return [int(x) for x in s[1:-1].split(',')]

This will give you the list without the commas.

Comments

0

ummm

elif s.startswith('['):
        return map(int,s[1:-1].split(","))

Comments

0

Currently you're converting a string to a list of characters. You want to be doing this:

map(int, str[1:-1].split(','))

That will give you the list of ints you are after.

Comments

0

I like the idea of using ConfigParser as @erewok mentioned, here's the whole "parser"

def parse(content):

    def parseList(content):
        # Recursive strategy
        listed = content.strip("[]").split(",")
        return map(parse, listed)

    def parseString(content):
        return content.strip("\"")

    def parseNumber(content):
        return int(content)

    def parse(content):
        if (content.startswith("\"")):
            return parseString(content)
        elif (content.startswith("[")):
            return parseList(content)
        elif (content.isdigit()):
            return parseNumber(content)

    # Create dictionary with values
    result = {}

    for line in content.splitlines():
        key, value = line.split("=",1)
        result[key] = parse(value)

    return result

I'm using a recursive strategy to sub-parse elements within the list you are getting, in case the list comes with numbers and strings mixed

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.