IsaacLevon
IsaacLevon

Reputation: 2580

Convert a list of objects to a dictionary of lists

I have a list of JSON objects, already sorted (by time let's say). Each JSON object has type and status. For example:

[
    {'type': 'A', 'status': 'ok'},
    {'type': 'B', 'status': 'ok'},
    {'type': 'A', 'status': 'fail'}
]

I'd like to convert it to:

{
    'A': ['ok', 'fail'],
    'B': ['ok']
}

So of course it's an easy task but I'm looking for the Pythonic way doing that, so it will spare me a few lines of code

Upvotes: 3

Views: 3771

Answers (3)

GG.
GG.

Reputation: 21904

A one-liner with multiple list comprehensions and sorted(set(…)) to remove the duplicate keys:

original = [
    {"type": "A", "status": "ok"},
    {"type": "B", "status": "ok"},
    {"type": "A", "status": "fail"},
]

result = {
    key: [x["status"] for x in original if x["type"] == key]
    for key in sorted(set([x["type"] for x in original]))
}

Output:

{'A': ['ok', 'fail'], 'B': ['ok']}

Upvotes: 1

Krishna Chaurasia
Krishna Chaurasia

Reputation: 9600

I don't know if there is a one-liner but you can make use of setdefault or defaultdict to achieve the desired result as:

data = [
    {'type': 'A', 'status': 'ok'},
    {'type': 'B', 'status': 'ok'},
    {'type': 'A', 'status': 'fail'}
]

Using setdefault():

res = {}
for elt in data:
    res.setdefault(elt['type'], []).append(elt['status'])

Output:

{'A': ['ok', 'fail'], 'B': ['ok']}

Using defaultdict:

from collections import defaultdict
res = defaultdict(list)
for elt in data:
    res[elt['type']].append(elt['status'])

Output:

defaultdict(<class 'list'>, {'A': ['ok', 'fail'], 'B': ['ok']})

Upvotes: 1

lllrnr101
lllrnr101

Reputation: 2343

Since your new structure depends on older (already processed) keys also, I doubt you can use dictionary comprehension (which operates on per-key basis) to achieve the required final state.

I would prefer to use defaultdict where each default key is a list.

from collections import defaultdict
new_data = defaultdict(list)
for item in data:
    new_data[item['type']].append(item['status'])
print(new_data)

which gives output:

defaultdict(<class 'list'>, {'A': ['ok', 'fail'], 'B': ['ok']})

Upvotes: 1

Related Questions