简体   繁体   中英

Python - Create a dict from a txt file

We are given a file (.txt) in the form:

Johnson, Joana
Volleyball Club
Erickson, John
Mcdonald, Joe

Smith, Johnny
Debate Club
Chess Club
McIlroy, Molly
Dino, Dennis

Jackson, Jamie
Gibson, Ginny
Fried, John

I have to write a function which calls this file and returns a dictionary in the form: {'first person's name' : [list of friends within each stanza] so this should be returned:

{'Johnson, Joana': ['Erickson, John', 'Mcdonald, Joe'], 'Smith, Johnny': ['McIlroy, Molly', 'Dino, Dennis'], 'Jackson, Jamie': ['Gibson, Ginny', 'Fried, John']}

I wrote a function below but it only processes the first stanza of the file instead of all of it, so it returns:

{'Johnson, Joana': ['Erickson, John', 'Mcdonald, Joe']}

I am only a beginner in python so if someone can help me without complicating it I would really appreciate it, I cannot seem to process the whole file

def name_to_friends(file):

    '''(file open for reading) -> dict of {str: list of str}
    '''

    for line in file:
        dic = {}
        lst = []
        for line in file:
            if line == '\n':
                dic.update({lst[0]:lst[1:]})
                break
            else:
                name = line.strip()        
                if ',' in line:
                    lst.append(line)
    return dic

You're almost there; remove the break ; and clear the list object each time you add another name and friends to your dictionary:

def name_to_friends(file):
    for line in file:
        dic = {}
        lst = []
        for line in file:
            if line == '\n':
                dic.update({lst[0]:lst[1:]})
                lst = []
            else:
                name = line.strip()        
                if ',' in line:
                    lst.append(line)

        if lst:
            dic.update({lst[0]:lst[1:]})

    return dic

The last if lst is needed for when there is no empty line at the end of the file.

Your break statement would stop reading the file altogether the first time you encountered an empty line; by removing it you get to continue to the next block.

A more idiomatic method would be:

def name_to_friends(file):
    dic = {}

    for line in file:
        line = line.strip()
        # skip empty lines until we find the start of a block
        if not line:
            continue

        friends = dic[line] = []
        for line in file:
            line = line.strip()
            if not line:
                break  # end of block, continue to the next list of friends
            if ',' in line:
                friends.append(line)

    return dic

This nests a second loop over the file lines inside the first; this advances the file line reading position too, so when the inner loop stops (because the file is done or we just read an empty line), the outer loop will continue reading where we left off.

if the file is not too large you could simply do something like

{k[0]: k[1:] for k in [l.split('\n') for l in file.read().split('\n\n')]}

Edit: to remove clubs (no comma) you could

{k[0]: [fr for fr in k[1:] if ',' in fr] for k in [ln.split('\n') for ln in file.read().split('\n\n')]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM