snippetpythonMinor
Parse a list of people to determine who likes someone
Viewed 0 times
likeswhosomeoneparsepeopledeterminelist
Problem
I have a data file that looks like this:
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':
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.
Which generates the output
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.