Filter List of Dictionaries and omit keys

Question:

I have a list of dictionaries:

resp = [
    {
        'meter_id': {'S': 'M#G000140'},
        'meter_reading_reader': {'S': 'Meyer'},
        'meter_reading_date': {'S': '2021-12-21T12:00:00'},
        'item_type': {'S': 'READING'},
        'meter_reading_value': {'S': '225'},
        'meter_reading_unit': {'S': 'cbm'},
        'meter_kind': {'S': 'Gas'},
        'month': {'S': 'December'},
        'year': {'S': '2021'},
        'SK': {'S': 'MPID#P-00002-01-MG-001'},
        'building_id': {'S': 'B#BUI-00001'},
        'PK': {'S': 'READ#G000140#2021#Dec'},
        'meter_serial_number': {'S': '7GMT0008942175'}
    },
    {
        'meter_id': {'S': 'M#G000155'},
        'meter_reading_reader': {'S': 'Meyer'},
        'meter_reading_date': {'S': '2022-02-28T12:00:00'},
        'item_type': {'S': 'READING'},
        'meter_reading_value': {'S': '45'},
        'meter_reading_unit': {'S': 'cbm'},
        'meter_kind': {'S': 'Gas'},
        'month': {'S': 'February'},
        'year': {'S': '2022'},
        'SK': {'S': 'MPID#P-00002-01-MG-001'},
        'building_id': {'S': 'B#BUI-00001'},
        'PK': {'S': 'READ#G000155#2022#Feb'},
        'meter_serial_number': {'S': '7GMT0008942175'}
    }
]

that I want to filter to show only 2 key-Value pairs – ‘meter_reading_date’ and ‘meter_reading_value’. So far I can filter with one value.

for item in resp:
    details = item['meter_reading_value']
     print(details)

That gives me:

{'S': '225'}
{'S': '45'}
{'S': '12'}

but what I want to achieve is the following:

{
    'meter_reading_date': '2021-12-21T12:00:00',
    'meter_reading_value': '225'
},
{
    'meter_reading_date': '2022-02-28T12:00:00',
    'meter_reading_value': '45'
},

How is that achievable?

Asked By: aerioeus

||

Answers:

You can do something like that

lst = []
keys = ['meter_reading_date', 'meter_reading_value']
for item in resp:
    d = {}
    for key in keys:
        d[key] = list(item[key].values())[0]
    lst.append(d)

Or one liner with comprehensions

lst = [{key: list(item[key].values())[0] for key in keys} for item in resp]

Output

[{'meter_reading_date': '2021-12-21T12:00:00', 'meter_reading_value': '225'},
 {'meter_reading_date': '2022-02-28T12:00:00', 'meter_reading_value': '45'}]

list(item[key].values())[0] can be replaced with item[key]['S'] if this key is permanent.

Answered By: Guy
  1. Iterate through the list and then through the dict.

  2. Create dict from the results and append to a list.

    res = []
    for z in d:
        for y in z.values():
            temp = {}
            temp['meter_reading_date'] = y['S']
            temp['meter_reading_value'] = y['S']
            res.append(temp)
    print(res)
Answered By: Ron Nowogrodski

With operator.itemgetter (to extract by parent/child keys):

from operator import itemgetter

keys = ('meter_reading_date', 'meter_reading_value')
p_keys, c_key = itemgetter(*keys), itemgetter('S')
res = [dict(zip(keys, (c_key(d_) for d_ in p_keys(d)))) for d in resp]
print(res)

[{'meter_reading_date': '2021-12-21T12:00:00', 'meter_reading_value': '225'}, {'meter_reading_date': '2022-02-28T12:00:00', 'meter_reading_value': '45'}]
Answered By: RomanPerekhrest

There are a number of good answer here and they allow for easy extension via enumeration of keys. However, if you know the keys you are interested in and this is not too dynamic, I think the most straightforward thing to do is just use them:

res = [
    {
        "meter_reading_date" : item["meter_reading_date"]["S"],
        "meter_reading_value" : item["meter_reading_value"]["S"],
    }
    for item in resp
]

print(res)
Answered By: JonSG

If the values (dictionaries) associated with meter_reading_date and meter_reading_value are guaranteed to have just one key – i.e., ‘S’ then:

KEYS = ('meter_reading_date', 'meter_reading_value')

output = [{k: d[k]['S'] for k in KEYS} for d in resp]

print(output)

Output:

[{'meter_reading_date': '2021-12-21T12:00:00', 'meter_reading_value': '225'}, {'meter_reading_date': '2022-02-28T12:00:00', 'meter_reading_value': '45'}]
Answered By: DarkKnight
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.