A common pattern in building RESTful web services is the serialization of internal state into a JSON structure for transmission.  Writing this serialization in a way that is clear and easy to understand helps improve code quality and maintainability.  Using Python’s list comprehension can help us achieve these aims.

For the purposes of this article, let us consider a simple toy example.  We’ll create an “Order” object that can be populated with “Inventory” items.  In our response we’ll want to publish a JSON object listing of all our orders and the items in each order that were ordered for express delivery.

from typing import List
from uuid import uuid4
 
# Sample classes for building our data structure
class Inventory:
    def __init__(self, name: str, express: bool=False):
        self.name = name
        self.express = express
        self.id = str(uuid4())
 
class Order:
    def __init__(self, first: str, last: str, items: List[Inventory]):
        self.first = first
        self.last = last
        self.items = items
        self.id = str(uuid4())
 
# Build a sample data set
orders = [
    Order('John', 'Smith', [
        Inventory('Apple', True),
        Inventory('Sausage'),
        Inventory('Eggs')
    ]),
    Order('Hildred', 'Spencer', []),
    Order('Candice', 'Silvester', [
        Inventory('Ham', True),
        Inventory('Potato', True)
    ]),
]

To serialize this structure into a JSON response there are a number of ways we could approach the problem.  Let us first consider how we might build this out piece by piece. In this first example we first iterate over the list of orders. Then we will iterate over the items in the order adding serializations if the item is ordered with express delivery. With that complete we then serialize the order and add it to the list of serialized orders. This code is perfectly functional, but the structure of our serialization is hidden among the logic statements. How might we go about improving readability of this code?

order_list = []
for order in orders:
    items = []
    for item in order.items:
        if item.express:
            item_status = {
                'id': item.id,
                'name': item.name,
            }
            items.append(item_status)
    order_status = {
        'name': ' '.join((order.first, order.last)),
        'id': order.id,
        'items': items,
    }
    order_list.append(order_status)
status = {
    'orders': order_list,
}

We can start by using a list comprehension to simplify our loop for building the item list. This collapses the inner loop down in to a single line.

order_list = []
for order in orders:
    items = [{'id': item.id, 'name': item.name} for item in order.items if item.express]
    order_status = {
        'name': ' '.join((order.first, order.last)),
        'id': order.id,
        'items': items,
    }
    order_list.append(order_status)
status = {
    'orders': order_list,
}

However, we can keep going by creating a nested list comprehension to subsume the outer loop as well.  Doing so allows us to simplify further.  Now if we were simply concerned about line count, this could reduce our serialization down to just a few lines. However, readability and line length matter as well. So instead, let’s expand the list comprehension across multiple lines to create our final serialization code.  A complete copy of the final code is available as a gist here.

status = {
    'orders': [
        {
            'name': ' '.join((order.first, order.last)),
            'id': order.id,
            'items': [
                {
                    'name': inventory.name,
                    'id': inventory.id,
                }
            for inventory in order.items if inventory.express  # Nested list comprehension with conditional statement
            ]
        }
        for order in orders  # Simple list comprehension to iterate over the orders in the list
    ]
}

It should now be clearly obvious to any reader what the structure of our JSON object is. If we compare this code to the JSON it generates, we can see how they visually resemble each other.

{
    "orders": [
        {
            "name": "John Smith",
            "id": "7e5369c2-a8af-4205-becc-6c05dde7bf2c",
            "items": [
                {
                    "id": "d7f14359-a758-46b3-8ba0-cd515daf6c32",
                    "name": "Apple"
                }
            ]
        },
        {
            "name": "Hildred Spencer",
            "id": "b5d413a8-ac24-43a7-8b12-6ee5c0a34cd2",
            "items": []
        },
        {
            "name": "Candice Silvester",
            "id": "eea4d01a-334f-4259-a0e2-8f5879684a25",
            "items": [
                {
                    "id": "52040e4d-1cb3-47ab-b9d4-d7959ce10d00",
                    "name": "Ham"
                },
                {
                    "id": "e68e0a7c-7092-47e1-b3bc-e04d113ab446",
                    "name": "Potato"
                }
            ]
        }
    ]
}

Using list comprehensions like this can help us express the creation of data structures in a way that is natural and clean.  This example focused on creating a dictionary for consumption by a JSON serializer, but the principal can be applied to many other cases.  Consider the creation of a nested structure of objects such as the sample data set used in this example.  How might we have constructed it had we been given another data structure, such as JSON perhaps, to generate it?  Are there places in your code where this could be applicable?