Aus zwei mach eins, Elemente mit gleicher ID zusammen führen

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
Papp Nase
User
Beiträge: 139
Registriert: Dienstag 11. März 2014, 15:12

Hallo,

ich habe mir einen kleines Sortierprogramm ausgedacht. Gegeben ist eine Liste mit 6 Obst- und Gemüsesorten (meine IDs):
Rotkohl
Weiskohl
Apfel
Kartoffel
Zitrone
Birne

Zu jeder ID gibt es zwei Attribute - Farte mit Farbwert und Gewicht mit Gewichtswert.

Jedes Attribut befindet sich einzeln als Element in einer Liste mit der dazugehörigen ID:

[ID,Attribut1,Wert], [ID,Attribut2,Wert]

Ich möchte folgendes haben:

[ID,Attribut1,Wert,Attribut2,Wert]

Ich habe mir dazu ein kleines Programm ausgedacht, dass auch recht gut funktioniert:

Code: Alles auswählen

# Testprogramm Liste mit zwei Eigenschaften zusammenfuehren
Liste = ["Rotkraut,Farbe,gruen", "Weisskraut,Gewicht,16", "Rotkraut,Gewicht,30","Apfel,Gewicht,14","Kartoffel,Farbe,grau","Zitrone,Farbe,gelb","Birne,Gewicht,4",
"Weisskraut,Farbe,weiss","Zitrone,Gewicht,1","Kartoffel,Gewicht,23","Apfel,Farbe,gruen","Birne,Farbe,gruen"]
newList = []
i = 1
for k in Liste:
    split_k = k.split (",")    
    for l in Liste[i:]:
        split_l = l.split (",")
        if split_k[0] == split_l[0]:
            if split_k[1] == "Gewicht":
                newString = split_k[0], split_k[1], split_k[2], split_l[1], split_l[2]
            else:
                newString = split_k[0], split_l[1], split_l[2], split_k[1], split_k[2]                
            newList.append(newString)
    i = i+1
print newList
Es gibt ja immer viele Lösungen und manchmal kann ein Programmieransatz zwar funktionieren, aber es kann ungünstig gelöst sein und bei langen ungeordneten Datenlisten mit vielleicht auch ungünstig sein. Es könnte ja auch sein, dass noch weitere Attribute hinzukommen, dann könnte ich zwar eine dritte for-Schleife einbauen, aber ich habe irgendwie Bauchschmerzen mit zu vielen ineinander verschachtelten for-Schleifen, auch die Sortierung der Reihenfolge der Attribute ist bei zwei Elementen eine einfache if-else-Bedingung, bei drei Attributen sieht das ganze schon anders aus - da muss ich dann mehr Möglichkeiten abtesten.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Papp Nase hat geschrieben:Es gibt ja immer viele Lösungen...
Und auch viele Datenstrukturen... :wink: Vielleicht wäre ja statt Deiner Liste mit der ID als erstes "Erkennungselement" ein Dictionary besser geeignet:

Code: Alles auswählen

>>> import collections
>>> food = collections.defaultdict(list)
>>> food['Rotkraut'].append('Farbe')
>>> food['Rotkraut'].append('gruen')
>>> food['Rotkraut']
['Farbe', 'gruen']
Wobei ich nicht verstehe, weshalb Du den Namen des Wertes samt dem Wert in einer Liste haben möchtest? Hast Du schon über Klassen nachgedacht?

Code: Alles auswählen

>>> class Food(object):
...     def __init__(self, color, weight):
...         self.color = color
...         self.weight = weight
... 
>>> rotkraut = Food(color='gruen', weight=30)
>>> rotkraut.color
'gruen'
>>> rotkraut.weight
30
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Papp Nase: eine Liste verschachtelt durchzugehen bedeutet einen Aufwand der Ordnung n². Ein Dictionary würde das in ein Lineares Problem (Du gehst die Liste nur einmal durch) reduzieren. Das ist nicht nur schneller, sondern auch leichter zu verstehen und weniger komplex und damit fehleranfällig.
BlackJack

@Papp Nase: Als Ziel solltest Du lieber ``(ID, [(Attribut1, Wert), (Attribut2, Wert)])`` haben. Man sollte in Listen nur Elemente haben die für den verarbeitenden Algorithmus alle die gleiche Bedeutung haben. Sonst wird der Code schnell sehr unübersichtlich wenn verschiedene Elemente unterschiedliche Bedeutung haben und über magische Indexwerte identifiziert werden.

Eventuell wäre, je nach dem was mit der Datenstruktur weiter passieren soll, auch ``{ID: {Attribut1: Wert, Attribut2: Wert}}`` eine günstigere Datenstruktur.

Und ich schliesse mich mutetella an: Wenn man anfängt zu tief zu schachteln, sollte man über dedizierte Typen in Form von Klassen nachdenken.
Papp Nase
User
Beiträge: 139
Registriert: Dienstag 11. März 2014, 15:12

Hallo,

vielen Dank für Eure vielen Antworten.
Antworten