HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonMinor

Parse a list of people to determine who likes someone

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
likeswhosomeoneparsepeopledeterminelist

Problem

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))

Solution

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) < 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'}

Code Snippets

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) < 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)
{'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'}

Context

StackExchange Code Review Q#84292, answer score: 2

Revisions (0)

No revisions yet.