Seite 1 von 1

Problem mit Zusammenfassung von Dictionaries in Liste

Verfasst: Dienstag 4. Juli 2006, 19:11
von keboo
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

Verfasst: Dienstag 4. Juli 2006, 22:32
von 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:``.

Verfasst: Mittwoch 5. Juli 2006, 09:07
von keboo
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

Verfasst: Mittwoch 5. Juli 2006, 15:47
von 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?