Problem mit Zusammenfassung von Dictionaries in Liste

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

hallo Leute,

Hab noch ein Problem mit der Zusammenfassung von Dictionnaries in einer Liste:

Folgende Liste, mit verschiedenen Dictinaries hab ich vorliegen:

Code: Alles auswählen

dict_list = 
[{'ID': '1', 'Width': '    3.000', 'Weight': '  322.378',  'Area': '    18.523'},
{'ID': '1', 'Width': '    4.000', 'Weight': '  352.338',  'Area': '    18.543'},
{'ID': '2', 'Width': '    3.000', 'Weight': '  362.318',  'Area': '    18.233'},
{'ID': '2', 'Width': '    2.000', 'Weight': '  312.328',  'Area': '    18.133'},
{'ID': '2', 'Width': '    1.000', 'Weight': '  322.368',  'Area': '    18.233'},
{'ID': '2', 'Width': '    1.000', 'Weight': '  322.368',  'Area': '    18.233'},
{'ID': '3', 'Width': '    1.000', 'Weight': '  322.368',  'Area': '    18.233'},
{'ID': '3', 'Width': '    1.000', 'Weight': '  322.368',  'Area': '    18.233'}]
Wie kann ich alle Weights per Schleife mit gleicher ID aufsummieren und diese dann in eine Ergebnisliste schreiben.

Diese Konstruktion scheitert, weil die IDs nicht richtig zugeordnet sind:


Code: Alles auswählen

weights = []                     

helpvar=''

for i in range(len(dict_list)):

    dict1 = dict_list[i]

    if helpvar != dict1.get('ID'):
        weights.append(float(dict1.get('Weight')))
        print 'Weight: ', dict1.get('Weight'), dict1.get('ID')
        print 'Summe:', sum(weights)
        print '\n'
        weights = [] # Leeren der Gewichtsliste

    else:
        print 'Weight: ', dict1.get('Weight'), dict1.get('ID')
        weights.append(float(dict1.get('Weight')))
        

    helpvar = dict1.get('ID') # Problemursprung?

print 'Summe: ', sum(weights)

Bitte um Hilfe, wie ich die FOR Schleife richtig stellen kann. Ich hab irgendwie das Gefühl, dass es sicher einen nicht so umständlichen und vor allem zielführenderen Weg zur Lösung gibt.

Danke,

Johannes
BlackJack

Deinem Quelltext konnte ich nicht so ganz folgen.

Am besten ist es Du sortierst die Liste erstmal nach IDs. Das ist sie im Beispiel schon, aber ich weiss nicht ob das immer gegeben ist!?

Und dann kann man die `itertools.groupby()` Funktion benutzen um aufeinanderfolgende Dictionaries mit der gleichen ID zu gruppieren und die kann man dann aufaddieren.

Code: Alles auswählen

from itertools import groupby
from operator import itemgetter
from pprint import pprint

dicts = [{'Area': '    18.523',
          'ID': '1',
          'Weight': '  322.378',
          'Width': '    3.000'},
         {'Area': '    18.543',
          'ID': '1',
          'Weight': '  352.338',
          'Width': '    4.000'},
         {'Area': '    18.233',
          'ID': '2',
          'Weight': '  362.318',
          'Width': '    3.000'},
         {'Area': '    18.133',
          'ID': '2',
          'Weight': '  312.328',
          'Width': '    2.000'},
         {'Area': '    18.233',
          'ID': '2',
          'Weight': '  322.368',
          'Width': '    1.000'},
         {'Area': '    18.233',
          'ID': '2',
          'Weight': '  322.368',
          'Width': '    1.000'},
         {'Area': '    18.233',
          'ID': '3',
          'Weight': '  322.368',
          'Width': '    1.000'},
         {'Area': '    18.233',
          'ID': '3',
          'Weight': '  322.368',
          'Width': '    1.000'}]

dicts.sort(key=itemgetter('ID'))
weights = [(key, sum(float(item['Weight']) for item in items))
           for key, items in groupby(dicts, itemgetter('ID'))]

pprint(weights)
Ausgabe:

Code: Alles auswählen

$ python test.py
[('1', 674.71600000000001),
 ('2', 1319.3819999999998),
 ('3', 644.73599999999999)]
Das ``for i in range(len(dict_list))`` ist übrigens ziemlich "unpythonisch". Du kannst gleich über die Liste iterieren ohne das Du den Index `i` brauchst: ``for dict1 in dict_list:``.
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Danke für die super Antwort!

Kannst du vielleicht zum besseren Verständnis für mich, dieses Schleifenkonstrukt

Code: Alles auswählen

weights = [(key, sum(float(item['Weight']) for item in items))
           for key, items in groupby(dicts, itemgetter('ID'))]
ein wenig entschachtelen. Das ist mir ein wenig zu hoch :)

LG
Johannes
BlackJack

keboo hat geschrieben:Kannst du vielleicht zum besseren Verständnis für mich, dieses Schleifenkonstrukt

Code: Alles auswählen

weights = [(key, sum(float(item['Weight']) for item in items))
           for key, items in groupby(dicts, itemgetter('ID'))]
ein wenig entschachtelen. Das ist mir ein wenig zu hoch :)

Code: Alles auswählen

weights = list()
for key, items in groupby(dicts, itemgetter('ID')):
    weights.append(key, sum(float(item['Weight']) for item in items))
Besser?
Antworten