Search code examples
pythonformattinglist-comprehension

Best Practice to Format Large List Comprehension?


I have a collection of rather large objects from which I only need 4 data points, they look like the following:

{
    'date': '01/01/1900'
    'info': {'contact': 'Jane Doe',
             'id': 298342,
             'address': '123 Street Rd.'},
    'account': {'name': 'Random Event Name',
                'id': 9623075},
    'guest_count': 523,
    'rooms': [{'name': 'Room A',
               'id': 209353,
               'capacity': 300},
              {'name': 'Room B',
               'id': 630923,
               'capacity': 50}],
    'start_time': '10:00:00',
    'end_time': '15:45:00',
              .
              .
              .
}

I have a simple for loop to iterate through the objects and pull the information out that I need:

info = []
for event in events:

    start_time = event['start_time']

    location = 'Offsite' if event['rooms'][0]['name'] == 'Offsite' else 'In-House'

    name = event['account']['name']

    guest_count = event['guest_count']

    info.append([start_time, location, name, guest_count])

Which I then converted to the following list comprehension:

info = [[event['start_time'], 'Offsite' if event['rooms'][0]['name'] == 'Offsite' else 'In-House', event['account']['name'], event['guest_count']] for event in events['results']]

This definitely breaks the 80 character rule and can't seem to find any documentation on how to format variable heavy list comprehension.

This is what I ended up doing, but it still seems rather ugly:

sanitized_events = [
    [event['start_time'], 
    'Offsite' if event['rooms'][0]['name'] == 'Offsite' else 'In-House', 
    event['account']['name'], 
    event['guest_count']] for event in events]

Solution

  • Some pieces of code are not supposed to be collapsed to a list comprehension. If you try and it seems to get more complex, then it is worth asking if it was a right path to begin with.

    One path to consider is always a helper function

    def _sanitize(event):
      location = 'Offsite' if event['rooms'][0]['name'] == 'Offsite' else 'In-House'
      return (event['start_time'],
              location,
              event['account']['name'],
              event['guest_count'])
    
    sanitized_events = [_sanitize(event) for event in events]
    

    which splits the logic of list creation from the processing, thus making it easier to comprehend the high level idea, while being able to jump to details if needed.