whopper510
whopper510

Reputation: 487

Split, edit, and replace values in list

having trouble doing some email text munging. I have participant sign ups in a list like this:

body=['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 
      'Location: Some Place','Participant: John Doe','Study: Study 1', 
      'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM',
      'Location: Some Place','Participant: Mary Smith']

I'm new to using python, so I'm not sure if there a specific name for the operation I want. Practically, what I want is to take the list items with the 'Participant: tag, remove that tag, and split the names up into separate list items for first and last names. So, something like this:

 body=['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 
       'Location: Some Place','John' ,'Doe']

I've tried using a list comprehension similar to here:

[item.split(' ')[1:] for item in body if re.match('Participant:*', item)]

which gives me back a nested list like this:

[['John', 'Doe'],['Mary','Smith']]

But, I have no idea how to make those nested lists with the first and last names into single list items, and no idea how to insert them back into the original list.

Any help is much appreciated!

Upvotes: 0

Views: 251

Answers (2)

mgilson
mgilson

Reputation: 309929

IMHO, this sort of thing is cleanest with a function:

def do_whatever(lst):
    for item in lst:
        if item.startswith('Participant:'):
           head, tail = item.split(':', 1)
           for name in tail.split():
               yield name
        else:
           yield item

body = list(do_whatever(body))

e.g.:

>>> def do_whatever(lst):
...     for item in lst:
...         if item.startswith('Participant:'):
...            head, tail = item.split(':', 1)
...            for name in tail.split():
...                yield name
...         else:
...            yield item
... 
>>> body=['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 
...       'Location: Some Place','Participant: John Doe','Study: Study 1', 
...       'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM',
...       'Location: Some Place','Participant: Mary Smith']
>>> body = list(do_whatever(body))
>>> body
['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 'Location: Some Place', 'John', 'Doe', 'Study: Study 1', 'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM', 'Location: Some Place', 'Mary', 'Smith']

Sorry for the really bad function name -- I'm not feeling creative at the moment...

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1122282

You can have you cake and eat it with:

[elem
 for line in body
 for elem in (line.split()[1:] if line.startswith('Participant:') else (line,))]

This produces output in a nested loop, where the inner loop either iterates over the split output or a tuple with one element, the unsplit list element:

>>> from pprint import pprint
>>> body=['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 
...       'Location: Some Place','Participant: John Doe','Study: Study 1', 
...       'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM',
...       'Location: Some Place','Participant: Mary Smith']
>>> [elem
...  for line in body
...  for elem in (line.split()[1:] if line.startswith('Participant:') else (line,))]
['Study: Study 1', 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM', 'Location: Some Place', 'John', 'Doe', 'Study: Study 1', 'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM', 'Location: Some Place', 'Mary', 'Smith']
>>> pprint(_)
['Study: Study 1',
 'Date:  Friday, March 28, 2014 3:15 PM - 4:00 PM',
 'Location: Some Place',
 'John',
 'Doe',
 'Study: Study 1',
 'Date: Friday, March 28, 2014 4:00 PM - 4:40 PM',
 'Location: Some Place',
 'Mary',
 'Smith']

Upvotes: 2

Related Questions