1
votes

Liste des dict à la liste des dict imbriqués en Python

J'ai input_data comme ceci:

output_data = [{'vehicle': '001',
            'store': [{'store': 'foo1', 'qty': [100, 200]},
                      {'store': 'baz1', 'qty': [300, 400]},
                      ]
            },
           {'vehicle': '002',
            'store': [{'store': 'foo2', 'qty': [500]},
                      {'store': 'baz2', 'qty': [600, 700]},
                      ]
            }]

Quelle est la meilleure façon en Python pour que les données out_put ressemblent à ce qui suit :

input_data = [
        {'vehicle': '001', 'store': 'foo1',  'qty': 100},
        {'vehicle': '001', 'store': 'foo1', 'qty': 200},
        {'vehicle': '001', 'store': 'baz1', 'qty': 300},
        {'vehicle': '001', 'store': 'baz1', 'qty': 400},
        {'vehicle': '002', 'store': 'foo2', 'qty': 500},
        {'vehicle': '002', 'store': 'baz2', 'qty': 600},
        {'vehicle': '002', 'store': 'baz2', 'qty': 700}]


2 commentaires

Votre code s'il vous plaît


sujet similaire: stackoverflow.com/questions/3749512/python-group-by


4 Réponses :


1
votes

Vous pouvez essayer ceci, je suis sûr qu'il y a une manière élégante, mais je ne peux pas le comprendre pour le moment:

[{'vehicle': '001',
  'store': [{'qty': [300, 400], 'store': 'baz1'},
            {'qty': [100, 200], 'store': 'foo1'}]},
 {'vehicle': '002',
  'store': [{'qty': [600, 700], 'store': 'baz2'},
            {'qty': [500], 'store': 'foo2'}]}]

Sortie:

import pandas as pd

input_data = [
        {'vehicle': '001', 'store': 'foo1',  'qty': 100},
        {'vehicle': '001', 'store': 'foo1', 'qty': 200},
        {'vehicle': '001', 'store': 'baz1', 'qty': 300},
        {'vehicle': '001', 'store': 'baz1', 'qty': 400},
        {'vehicle': '002', 'store': 'foo2', 'qty': 500},
        {'vehicle': '002', 'store': 'baz2', 'qty': 600},
        {'vehicle': '002', 'store': 'baz2', 'qty': 700}]
df = pd.DataFrame(pd.DataFrame(input_data).groupby(['vehicle','store'])['qty'].apply(list))
dct = df.groupby(level=0).apply(lambda df: df.xs(df.name)['qty'].to_dict()).to_dict()
final_list = []
for k in dct:
    temp_dct = {}
    temp_dct['vehicle'] = k
    temp_l = [dict(zip(['store','qty'],[key,v])) for key,v in dct[k].items()]
    temp_dct['store'] = temp_l
    final_list.append(temp_dct)
print(final_list)


0 commentaires

0
votes

Vous pouvez utiliser itertools.groupby et operator.itemgetter

[{'vehicle': {'store': [{'qty': [100, 200], 'store': 'foo1'},
                        {'qty': [300, 400], 'store': 'baz1'}]}},
 {'vehicle': {'store': [{'qty': [500], 'store': 'foo2'},
                        {'qty': [600, 700], 'store': 'baz2'}]}}]

Results:

names = v, s, q = 'vehicle', 'store', 'qty'
v_key, s_key, q_key = map(itemgetter, names)
output_data = [{v: {s: [{s: sk, q: list(map(q_key, sv))}
                            for sk, sv in groupby(vv, s_key)]}}
                            for vk, vv in groupby(input_data, v_key)]


0 commentaires

0
votes

Une façon de le faire avec les itertools intégrés - méthode groupby :

# Input data
input_data = [
        {'vehicle': '001', 'store': 'foo1',  'qty': 100},
        {'vehicle': '001', 'store': 'foo1', 'qty': 200},
        {'vehicle': '001', 'store': 'baz1', 'qty': 300},
        {'vehicle': '001', 'store': 'baz1', 'qty': 400},
        {'vehicle': '002', 'store': 'foo2', 'qty': 500},
        {'vehicle': '002', 'store': 'baz2', 'qty': 600},
        {'vehicle': '002', 'store': 'baz2', 'qty': 700}]

# Main code
from itertools import groupby # For grouping a dataset

data = groupby(input_data, key = lambda x: x['vehicle']) # Grouping vehicles

final_data = []
for i in data:
    inner = {}
    outer = {}
    for j in list(i[1]):
        inner.setdefault(j['store'], []).append(j['qty'])
    outer["vehicle"] = i[0]
    outer["store"] = [{"store":i, "qty": j} for i, j in inner.items()]
    final_data.append(outer)

print (final_data)

# Output
# {'vehicle': '001', 'store': [{'store': 'foo1', 'qty': [100, 200]}, {'store': 'baz1', 'qty': [300, 400]}]}, {'vehicle': '002', 'store': [{'store': 'foo2', 'qty': [500]}, {'store': 'baz2', 'qty': [600, 700]}]}]

J'espère que cela aide et compte!


0 commentaires

0
votes

Le code ci-dessous produit la sortie attendue:

result_list = [] def check_duplicate (nom_véhicule): pour index, d dans enumerate (result_list): if d.get ("véhicule") == nom_véhicule: retourne True, index pour store_index, store_value dans enumerate (d.get ("store")): if store_value.get ("store") == nom_véhicule: renvoie True, store_index

if isinstance(data,dict) and  data.has_key("vehicle"):
    #print data
    result= check_duplicate(data.get('vehicle'))
    if not result[0]:
        result_list.append({'vehicle':data.get('vehicle'),'store':[{'store':data.get('store') , 'qty': [data.get('qty')]}]})

    if result[0]:
        print "check if store is already present"
        store_check= check_duplicate(data.get('store'))

        if store_check[0]:
            result_list[result[1]].get("store")[store_check[1]].get("qty").append(data.get('qty'))
        if not store_check[0]:
            result_list[result[1]].get("store").append({'store':data.get('store') , 'qty': [data.get('qty')]})

pour les données dans input_data:

return False,None

print result_list


0 commentaires