#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2

    Text File to Dictionary system


    So, I have a text file named fruits.txt, located relative to my script at .\\Lists\\, a working excerpt of which is included below:

    Code:
    ***
    Fruits,Exhaustive
    ***
    apple
    coconut
    grape
    purple mangosteen
    tomato
    uglifruit
    watermelon
    ***
    Fruits,Simple
    ***
    apple
    apricot
    avocado
    I'm trying to get a dictionary that has two keys, "Fruits,Exhaustive" containing the first set of items as a list, and "Fruits,Simple" containing the second set of items as a list.
    Here's my code so far:

    Code:
    def make_from_text(filename):
    	text=open(".\\Lists\\"+filename,'r')
    	ldict=dict()
    	getname=True
    	constr=list()
    	for line in text:
    		if (line=="***"):
    			if getname:
    				getname=False
    			else:
    				getname=True
    				constr.append((newname,newlist))
    				newname,newlist=str(),list()
    		if getname:
    			newname=line
    		else:
    			nline=line.replace(' ','').replace("""\n""",'') #strips whitespace
    			newlist.append(nline)
    	text.close()
    	for a,b in constr:
    		ldict[a]=b
    	return ldict
    calling make_from_text('fruits.txt') returns an empty dictionary.

    I'm guessing this has something to do with the fact that newname and newlist both get cleaned out. But I don't know how to make those into new items, fixing it. :\
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    line won't match '***' because of the newline. Is
    '***' in line
    reasonable? (Yes.)

    Handling file open/close outside the function makes good sense to me.

    newname,newlist=str(),list() were used before initialized.

    This code minimally does what I think you want. Minimally: it is not robust against bad files.
    Code:
    import io
    import pprint
    
    def odd(a):
        return a & 1
    
    def even(a):
        return not odd(a)
    
    def make_from_text(stream):
        result = dict()
        key = None
        state = 0
        for line in text:
            if '***' in line:
                state += 1
                continue
            stripped_line = line.strip()
            if odd(state):
                if 2 < state:
                    result[key] = value
                key = stripped_line
                value = []
            else:
                value.append(stripped_line.replace(' ',''))
        result[key] = value
        return result
    
    
    NOTYOURFILECONTENT = '''
        ***
        Fruits,Exhaustive
        ***
        apple
        coconut
        grape
        purple mangosteen
        tomato
        uglifruit
        watermelon
        ***
        Fruits,Simple
        ***
        apple
        apricot
        avocado
        ***
        dairy
        ***
        m i l k
    '''
    EFFECTIVEFILECONTENT = NOTYOURFILECONTENT.strip()
    
    
    try:
        text = open(".\\Lists\\"+filename,'r')
    except:
        text = io.StringIO(EFFECTIVEFILECONTENT)
    
    pprint.pprint(make_from_text(text))
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2
    Whoa. Thanks man.

    By the way, odd returns an int and even returns a boolean. I know it's a stylistic quibble, but it looks more than a little silly. :P

    Besides that, yeah, the code looks great. Thank you very much.

    EDIT: Also, what do I call you? You help me so much but I feel like I can never thank you properly because your username is a string of random-seeming characters. XD
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    My username IS a string of random characters. I'm Dave.

    I had considered writing

    even = lambda a:not(a&1)
    odd = lambda a: not even(a)

    to have them both return Boolean. Instead I decided, by hope not investigation, that 0 is interchangeable with False. Poor choice, I guess.

    Actually, at the time I didn't consider changing even making it in effect a triple negative.

    odd=lambda a:not not(a&1)
    even=lambda a:not odd(a)
    Last edited by b49P23TIvg; August 1st, 2013 at 10:24 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2
    Nice to meet you Dave. I'm Nicholas.

    I went with bool(a&1) , if you're dreadfully curious. :P

    Comments on this post

    • b49P23TIvg agrees : Nice, I didn't realize bool was a type.

IMN logo majestic logo threadwatch logo seochat tools logo