简体   繁体   中英

Sort python list into dictionary of lists, based on property in list

I'm trying to sort a list of objects in python into a dictionary of lists via a property of the objects in the original list

I've done it below, but this feels like something I should be able to do using a dictionary comprehension?

for position in totals["positions"]:
        if not hasattr(totals["positions_dict"], position.get_asset_type_display()):
            totals["positions_dict"][position.get_asset_type_display()] = []
        totals["positions_dict"][position.get_asset_type_display()].append(position)

Some self improvements

totals["positions_dict"] = {}
    for position in totals["positions"]:
        key = position.get_asset_type_display()
        if key not in totals["positions_dict"]:
            totals["positions_dict"][key] = []
        totals["positions_dict"][key].append(position)

You could use itertools.groupby and operator.methodcaller in a dict comprehension:

from operator import methodcaller
from itertools import groupby

key = methodcaller('get_asset_type_display')
totals["positions_dict"] = {k: list(g) for k, g in groupby(sorted(totals["positions"], key=key), key=key)}

Using a defaultdict as suggested by @Jean-FrançoisFabre allows you to do it with a single call to get_asset_type_display() in one loop:

from collections import defaultdict

totals["positions_dict"] = defaultdict(list)
for position in totals["positions"]:
    totals["positions_dict"][position.get_asset_type_display()].append(position)

Haven't tested this, because I don't have your data. And I think it's rather ugly, but it just may work:

totals ['positions_dict'] = {
    key: [
        position
        for position in totals ['positions']
        if position.get_asset_type_display () == key
    ]
    for key in {
        position.get_asset_type_display ()
        for position in totals ['positions']
    }
}

But I would prefer something very simple, and avoid needless lookups / calls:

positions = totals ['positions']
positions_dict = {}

for position in positions:
    key = position.get_asset_type_display ()
    if key in positions_dict:
        positions_dict [key] .append (position)
    else:
        positions_dict [key] = [position]


totals ['positions_dict'] = positions_dict
positions = totals ['positions']

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