简体   繁体   中英

Python comprehension, dictionary of lists

I can't get my head around this one. Or am I over complicating things? I'm trying to make this code more 'Pythonic'.

statuses = {record['id'] : [] for record in data}

for record in data:
    for status in record['statuses']:
        data = {
            'status_code': status['statusCode'],
            'short_desc': status['statusShortDesc'],
        }

        if 'statusLongDesc' in status:
            data.update({'long_desc': status['statusLongDesc']})
        else:
            data.update({'long_desc': ''})

        statuses[record['id']] += [data]
    }
}

Several challenges here, code below I know is wrong but I'm trying to get across what I want with out knowing how:

  • How do I update a list in a dictionary in a comprehension? Along the lines of this. Would this work? Something doesn't feel right about it to me. Have I got carried away with the curly brackets?

     statuses = { { record['id']: list({ 'status_code': status['statusCode'], 'short_desc': status['statusShortDesc'], 'long_desc': '' }) } for record in data for status in record['statuses'] } 

This produces TypeError: unhashable type: 'dict'

  • How can I then not repeat the data part like in my original code for adjusting long_desc? (My dictionary is actually a lot longer and it seems crazy to repeat it all for one line.) Like: then if 'statusLongDesc' in status list.extend('long_desc': status['statusLongDesc']) added to the above comprehension.

I wouldn't overcomplicate things. The biggest thing you can use to simplify your original is to use the get method.

statuses = {record['id']: [] for record in data}

for record in data:
    for status in record['statuses']:           
        statuses[record['id']].append({
            'status_code': status['statusCode'],
            'short_desc': status['statusShortDesc'],
            'long_desc': status.get('statusLongDesc', ''),
        })

Now, if you want, you can replace the loops with a dict comprehension that uses a list comprehension.

statuses = { record['id']: [{...} for status in record['statuses']] for record in data }

where {...} is the data dict in the original.

You can easily create list using comprehension, instead of .append ing:

statuses = {}

for record in data:
    statuses[record['id']] = [
        {
            'status_code': status['statusCode'],
            'short_desc': status['statusShortDesc'],
            'long_desc': status.get('statusLongDesc', ''),
        } for status in record['statuses']
    ]

It can also be done in one expression this way, if I got nested comprehensions right:

statuses = {
    record['id']: [{
            'status_code': status['statusCode'],
            'short_desc': status['statusShortDesc'],
            'long_desc': status.get('statusLongDesc', ''),
        } for status in record['statuses']
    ] for record in data
}

But I find it unreadable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM