Wieder Problem mit Zusammenfassung von Dictionnaries in List

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,

Ich hab folgende Liste:

Code: Alles auswählen

weights=
[{'C[kg]': 12, 'B[kg]': 34.7, 'A[kg]': 21}, 
{'C[kg]': 12.1, 'B[kg]': 34.3, 'A[kg]': 21.1}, 
{'C[kg]': 13, 'B[kg]': 34.2, 'A[kg]': 21},
{'C[kg]': 11, 'B[kg]': 31, 'A[kg]': 28.2},
{'C[kg]': 11.2, 'B[kg]': 37.4, 'A[kg]': 21}, 
{'C[kg]': 19, 'B[kg]': 34, 'A[kg]': 21},
{'C[kg]': 12.1, 'B[kg]': 31, 'A[kg]': 26}, 
{'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}]
Wie kann ich ein neues Dictionary erzeugen, in welchem die Summen der jeweiligen keys stehen?


Habs leider nicht geschafft mein letztes Dictionary Problem auf dieses Problem umzumünzen.

LG,

Johannes
Zuletzt geändert von keboo am Sonntag 9. Juli 2006, 13:00, insgesamt 1-mal geändert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

keboo hat geschrieben:Wie kann ich ein neues Dictionary erzeugen, in welchem die Summen der jeweiligen keys stehen?
Hi Johannes!

Code: Alles auswählen

weights = [
    {'C[kg]': 12, 'B[kg]': 34.7, 'A[kg]': 21},
    {'C[kg]': 12.1, 'B[kg]': 34.3, 'A[kg]': 21.1},
    {'C[kg]': 13, 'B[kg]': 34.2, 'A[kg]': 21},
    {'C[kg]': 11, 'B[kg]': 31, 'A[kg]': 28.2},
    {'C[kg]': 11.2, 'B[kg]': 37.4, 'A[kg]': 21},
    {'C[kg]': 19, 'B[kg]': 34, 'A[kg]': 21},
    {'C[kg]': 12.1, 'B[kg]': 31, 'A[kg]': 26},
    {'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
] 

sum_dict = {}

# Jedes Dictionary durchlaufen und die Werte addieren
for weight_dict in weights:
    for key, value in weight_dict.items():
        sum_dict[key] = sum_dict.get(key, 0) + float(value)

print sum_dict
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Andere Möglichkeit:

Code: Alles auswählen

new = {}

for i in weights[0].keys():
    new[i] = sum([weights[j][i] for j in range(len(w))])
Gruß, mawe
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mawe hat geschrieben:

Code: Alles auswählen

new[i] = sum([weights[j][i] for j in range(len(w))])
Hi mawe!

So gut mir deine Lösung auch gefällt, aber warum verwendest du keine aussagekräftigen Variablenamen? Beim Durchlesen deines Codes habe ich mich dabei ertappt, dass ich mir dachte: "i?? Wozu braucht man hier einen Zähler?"

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Du hast völlig recht gerold. Ich kann mir das nur schwer abgewöhnen (weiss gar nicht warum ich's mir angewöhnt habe :)). Ich arbeite dran ...
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Hi Leute,

Ich hätte noch eine weiterführende Frage:

In meiner Gewichtsliste ist mit "title" nun ein zusätzlicher Parameter zu finden.

Code: Alles auswählen

weights = [
    {'title': 'Part A 1', 'C[kg]': 12, 'B[kg]': 34.7, 'A[kg]': 21},
    {'title': 'Part A 2', 'C[kg]': 12.1, 'B[kg]': 34.3, 'A[kg]': 21.1},
    {'title': 'Part A 3', 'C[kg]': 13, 'B[kg]': 34.2, 'A[kg]': 21},
    {'title': 'Part B 1', 'C[kg]': 11, 'B[kg]': 31, 'A[kg]': 28.2},
    {'title': 'Part B 2', 'C[kg]': 11.2, 'B[kg]': 37.4, 'A[kg]': 21},
    {'title': 'Part B 3', 'C[kg]': 19, 'B[kg]': 34, 'A[kg]': 21},
    {'title': 'Part B 4', 'C[kg]': 12.1, 'B[kg]': 31, 'A[kg]': 26},
    {'title': 'Part C 1', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
    {'title': 'Part C 2', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
    {'title': 'Part C 3', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
    {'title': 'Part C 4', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
    {'title': 'Part C 5', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
    {'title': 'Part C 6', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22}
] 
Die Bezeichnungen Part A, Part B und Part C haben in meinem Skript keinen Zusammenhang. Wie kann ich nun 3 neue Dictionnaries (pro Part ein neues) erzeugen, die jeweils die Summen der Gewichter der jeweiligen Parts beinhalten?

Danke für eure Hilfe,

Johannes
BlackJack

Code: Alles auswählen

from itertools import groupby
from pprint import pprint

weights = [
     {'title': 'Part A 1', 'C[kg]': 12, 'B[kg]': 34.7, 'A[kg]': 21},
     {'title': 'Part A 2', 'C[kg]': 12.1, 'B[kg]': 34.3, 'A[kg]': 21.1},
     {'title': 'Part A 3', 'C[kg]': 13, 'B[kg]': 34.2, 'A[kg]': 21},
     {'title': 'Part B 1', 'C[kg]': 11, 'B[kg]': 31, 'A[kg]': 28.2},
     {'title': 'Part B 2', 'C[kg]': 11.2, 'B[kg]': 37.4, 'A[kg]': 21},
     {'title': 'Part B 3', 'C[kg]': 19, 'B[kg]': 34, 'A[kg]': 21},
     {'title': 'Part B 4', 'C[kg]': 12.1, 'B[kg]': 31, 'A[kg]': 26},
     {'title': 'Part C 1', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
     {'title': 'Part C 2', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
     {'title': 'Part C 3', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
     {'title': 'Part C 4', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
     {'title': 'Part C 5', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
     {'title': 'Part C 6', 'C[kg]': 13, 'B[kg]': 30, 'A[kg]': 22},
]

WEIGHT_KEYS = ('A[kg]', 'B[kg]', 'C[kg]')

def keyfunc(item):
    return item['title'][5]     # The part character.

def add_items(a, b):
    for key in WEIGHT_KEYS:
        a[key] += b[key]
    return a

weights.sort(key=keyfunc)
result = list()
for key, items in groupby(weights, keyfunc):
    zero = dict.fromkeys(WEIGHT_KEYS, 0)
    zero['part'] = key
    result.append(reduce(add_items, items, zero))

pprint(result)
Hier gibt's eine Funktion `keyfunc()` die den Schlüssel zum sortieren und gruppieren ermittelt, in diesem Fall also der Buchstabe. Falls die Liste immer nach Parts sortiert ist, dann kann man sich den `sort()` Aufruf sparen.

Die Parts werden dann mit `itertools.groupby()` gruppiert. In der Schleife wird ein Dictionary mit dem Partbuchstaben als ('part': buchstabe) Eintrag und einer 0 für jedes der Gewichte erzeugt und dann werden die Dictionaries des gleichen Parts mit der `reduce()` Funktion und einer geeigneten "Additionsfunktion" für zwei Dictionaries aufsummiert.

Ergebnis:

Code: Alles auswählen

$ python test.py
[{'A[kg]': 63.100000000000001,
  'B[kg]': 103.2,
  'C[kg]': 37.100000000000001,
  'part': 'A'},
 {'A[kg]': 96.200000000000003,
  'B[kg]': 133.40000000000001,
  'C[kg]': 53.300000000000004,
  'part': 'B'},
 {'C[kg]': 78, 'B[kg]': 180, 'A[kg]': 132, 'part': 'C'}]
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

hi blackjack!

danke für die super lösungshinweise!
das kann ich auch super bei einem anderen skript einsetzen.

lg
johannes
Antworten