Parse a list of people to determine who likes someone I have a data file that looks like this:




Friend Name                     Joe
Likes                           Jill
Age                             30
Gender                          Male

Friend Name                     
Likes                           Mark
Age                             30
Gender                          Male

Friend Name                     Bob
Likes                           Ralph
Age                             30
Gender                          Male



Note: the data file has leading spaces before the first column.

I want to parse this file and see who likes a given person (likes). In this example, at most only one person likes the given person. So, say I am finding who likes 'Ralph', only Bob does. It is possible that the likes is not even in the data. It is also possible that the Friend Name might be blank (see the second Friend).

Here is my code to parse this data and return the friend who likes 'likes':



def parse_friends_list(friends_list, likes):
    output = friends_list.strip().splitlines()
    for line in output:
        try:
            if line.startswith('Friend Name'):
                friend = line.split()[2]
            elif line.startswith('Likes'):
                found_likes = line.split()[1]
                if found_likes == likes and friend:
                    return friend
                friend = ''
        except IndexError:
            pass
    raise NoFriendParse('Unable to find a friend for {}'.format(likes))
I like to break problems like this up into a few steps, makes it easier for my brain to understand.

import re

raw_text = """Friend Name                     Joe
Likes                           Jill
Age                             30
Gender                          Male

Friend Name
Likes                           Mark
Age                             30
Gender                          Male

Friend Name                     Bob
Likes                           Ralph
Age                             30
Gender                          Male"""


def split_row(row):
    items = re.split('\s\s+', row)
    if len(items) &lt; 2:  # Value is blank
        return items[0], None
    return items


def parse_block(block):
    rows = block.split('\n')
    fields = map(split_row, rows)
    return dict(fields)


def process_text(text):
    blocks = text.split('\n\n')
    return map(parse_block, blocks)

if __name__ == '__main__':
    for like in process_text(raw_text):
        print(like)


Which generates the output

{'Likes': 'Jill', 'Friend Name': 'Joe', 'Age': '30', 'Gender': 'Male'}
{'Likes': 'Mark', 'Friend Name': None, 'Age': '30', 'Gender': 'Male'}
{'Likes': 'Ralph', 'Friend Name': 'Bob', 'Age': '30', 'Gender': 'Male'}