Hi Zusammen,
ich grüble schon seit geraumer Zeit an einer Schleife und finde keine Lösung. Vlt hat jemand nicht das Brett vor dem Kopf, wie ich.
Gegeben ist bspw. ein Produkt, bei dem vorher nicht feststeht, wie viele Produkteigenschaften und zugehörige Werte verfügbar sind:
ProduktData = [
["ProduktName1",
["ProduktEigenschaftsName1","Eigenschaft1Wert1", "Eigenschaft1Wert2","Eigenschaft1Wert3"],
["ProduktEigenschaftsName2","Eigenschaft2Wert1", "Eigenschaft2Wert2"],
["ProduktEigenschaftsName3","Eigenschaft3Wert1", "Eigenschaft3Wert2"]
]
]
Return ist eine Liste aller Varianten des Produkts.
Die Funktion soll also anhand eines Zählers erst einmal feststellen, wieviele Schleifen gebildet werden müssen.
Die Funktion soll also dann eine Liste liefern, die so aussieht:
[
["ProduktName1", "EigenschaftsName1", "Eigenschaft1Wert1", "ProduktEigenschaftsName2", "Eigenschaft2Wert1", "ProduktEigenschaftsName3", Eigenschaft3Wert1],
["ProduktName1", "EigenschaftsName1", "Eigenschaft1Wert2", "ProduktEigenschaftsName2", "Eigenschaft2Wert1", "ProduktEigenschaftsName3", Eigenschaft3Wert1],
["ProduktName1", "EigenschaftsName1", "Eigenschaft1Wert3", "ProduktEigenschaftsName2", "Eigenschaft2Wert1", "ProduktEigenschaftsName3", Eigenschaft3Wert1],
["ProduktName1", "EigenschaftsName1", "Eigenschaft1Wert1", "ProduktEigenschaftsName2", "Eigenschaft2Wert2", "ProduktEigenschaftsName3", Eigenschaft3Wert1],
... etc. (also insgesamt in dem Bsp: 3 x 2 x 2 Varianten
Habe schon ein paar Stunden mit itertools und eigenen Schleifen herumprobiert und gesucht und komme aber nicht weiter.
Hilfe wäre nett
Funktion "alle Produktkombinationen" mit dynamischer Anzahl der Eigenschaften
@tom79: wo sollen welche Schleifen gebildet werden? Ich sehe nur Listen.
Listen sind dazu da, gleichartige Objekte zu speichern, also entweder Produkte, oder nur Produktnamen, oder Eigenschaften, aber nicht Produktname, Eigenschaftname und Eigenschaftwert in einer Liste.
Bei solchen verschachtelten Werten ist es dann aber sinnvoller, passendere Datenstrukturen zu verwenden, also neben Listen auch Wörterbucher/Namedtuple/Klassen.
Zum Beispiel mit Wörterbüchern:
Wie willst Du diese Daten jetzt verarbeiten?
Listen sind dazu da, gleichartige Objekte zu speichern, also entweder Produkte, oder nur Produktnamen, oder Eigenschaften, aber nicht Produktname, Eigenschaftname und Eigenschaftwert in einer Liste.
Bei solchen verschachtelten Werten ist es dann aber sinnvoller, passendere Datenstrukturen zu verwenden, also neben Listen auch Wörterbucher/Namedtuple/Klassen.
Zum Beispiel mit Wörterbüchern:
Code: Alles auswählen
ProduktData = [
{
"name": "ProduktName1",
"eigenschaften": {
"Name1": ["Wert1", "Wert2", "Wert3"],
"Name2": ["Wert1", "Wert2"],
"Name3": ["Wert1", "Wert2"],
},
},
]
-
- User
- Beiträge: 60
- Registriert: Dienstag 4. Dezember 2018, 16:57
Basierend darauf könnte man so etwas machen (geht sicher auch hübscher).Sirius3 hat geschrieben: ↑Montag 4. März 2019, 16:24Code: Alles auswählen
ProduktData = [ { "name": "ProduktName1", "eigenschaften": { "Name1": ["Wert1", "Wert2", "Wert3"], "Name2": ["Wert1", "Wert2"], "Name3": ["Wert1", "Wert2"], }, }, ]
Code: Alles auswählen
list(itertools.product(*list(ProduktData[0]['eigenschaften'].values())))
-
- User
- Beiträge: 60
- Registriert: Dienstag 4. Dezember 2018, 16:57
Code: Alles auswählen
list(ProduktData[0]['eigenschaften'].keys())
- __blackjack__
- User
- Beiträge: 13006
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Sirius3: Kommt das nicht darauf an was man machen will/braucht? `keys()` liefert ja etwas `set`-artiges. Wenn der nächste Verarbeitungsschritt da eine Liste haben will, braucht man `list()`. Wenn's nur irgendwas iterierbares sein muss, dann nicht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
-
- User
- Beiträge: 60
- Registriert: Dienstag 4. Dezember 2018, 16:57
Komme mit den Keys nicht weiter, also den Namen der Eigenschaften.
Der Output sollte lauten:
[
["Produkteigenschaft1":"Wert1.1", "Produkteigenschaft2":"Wert2.1", "Produkteigenschaft3":"Wert3.1"],
["Produkteigenschaft1":"Wert1.2", "Produkteigenschaft2":"Wert2.1", "Produkteigenschaft3":"Wert3.1"],
...
]
Mit keys() erhalte ich zwar alle Labels, aber eben nicht an den zugehörigen Daten.
Der Output sollte lauten:
[
["Produkteigenschaft1":"Wert1.1", "Produkteigenschaft2":"Wert2.1", "Produkteigenschaft3":"Wert3.1"],
["Produkteigenschaft1":"Wert1.2", "Produkteigenschaft2":"Wert2.1", "Produkteigenschaft3":"Wert3.1"],
...
]
Mit keys() erhalte ich zwar alle Labels, aber eben nicht an den zugehörigen Daten.
Ok, mag sein, dass ich beim Format etwas geschlampt habe, aber darum gehts ja auch nicht, sondern um die Struktur.
Ob das dann in JSON oder Array rauskommt, ist egal. Mein Ziel ist, dass ich eine Struktur erhalte, die ich anschließend
mit einer Suchfunktion durchsuchen kann.
bsp:
Produkt 1 = Ford Mustang mit Eigenschaften: AnzahlTüren 2, 3, 4, 5 und Eigenschaft2: Farben Rot, Blau und Eigenschaft3 "Reifen": dicke und normale
Ich habe also:
ProduktData = [
{
"Produktname": ["Ford Mustang"],
"Eigenschaften": {
"Türen": [2,3,4,5],
"Farbe": [
"rot",
"blau",
],
"Reifen": [
"Dicke Reifen",
"normale Reifen",
],
},
},
]
Ein anderer Datensatz (das nächste Produkt), könnte eine andere Anzahl von Produkteigenschaften haben.
Nun soll die Funktion alle Möglichen Produktkonfigurationen auswerfen, und zwar unter Nennung des Fieldnames, damit ich später über
den Fieldname eine Abfrage auf die Liste machen kann und dann die besten Matches mit einem Suchstring anzeigen kann.
Meine Ergebnisdatensätze sollen also so aussehen:
[ ("Produktname": "Ford Mustang"), ("Eigenschaften": [("Türen": 2), ("Farbe": "rot "), ("Reifen": "dicke Reifen")]],
[nächste Konfigurationsmöglichkeit],
...
]
Ich kann mit dem Ergebnis der Liste a) eine Abfrage auf den Produktnamen und/oder eine bestimmte Eigenschaft inkl. zugehörigem Wert machen.
Ausgabeformat ist mir egal, weil ich den String ja ggf. noch anpassen kann. Gut natürlich, wenn's gleich passend käme.
Danke für die Hilfe.
Ob das dann in JSON oder Array rauskommt, ist egal. Mein Ziel ist, dass ich eine Struktur erhalte, die ich anschließend
mit einer Suchfunktion durchsuchen kann.
bsp:
Produkt 1 = Ford Mustang mit Eigenschaften: AnzahlTüren 2, 3, 4, 5 und Eigenschaft2: Farben Rot, Blau und Eigenschaft3 "Reifen": dicke und normale
Ich habe also:
ProduktData = [
{
"Produktname": ["Ford Mustang"],
"Eigenschaften": {
"Türen": [2,3,4,5],
"Farbe": [
"rot",
"blau",
],
"Reifen": [
"Dicke Reifen",
"normale Reifen",
],
},
},
]
Ein anderer Datensatz (das nächste Produkt), könnte eine andere Anzahl von Produkteigenschaften haben.
Nun soll die Funktion alle Möglichen Produktkonfigurationen auswerfen, und zwar unter Nennung des Fieldnames, damit ich später über
den Fieldname eine Abfrage auf die Liste machen kann und dann die besten Matches mit einem Suchstring anzeigen kann.
Meine Ergebnisdatensätze sollen also so aussehen:
[ ("Produktname": "Ford Mustang"), ("Eigenschaften": [("Türen": 2), ("Farbe": "rot "), ("Reifen": "dicke Reifen")]],
[nächste Konfigurationsmöglichkeit],
...
]
Ich kann mit dem Ergebnis der Liste a) eine Abfrage auf den Produktnamen und/oder eine bestimmte Eigenschaft inkl. zugehörigem Wert machen.
Ausgabeformat ist mir egal, weil ich den String ja ggf. noch anpassen kann. Gut natürlich, wenn's gleich passend käme.
Danke für die Hilfe.
- __blackjack__
- User
- Beiträge: 13006
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@tom79: Du schlampst bei der Notation der Struktur, wobei Dir die Struktur aber wichtig ist – das widerspricht sich. Man muss halt schon wissen was Du haben willst, und nicht nur so ungefähr, sondern *genau*. Das ist vielleicht auch Dein Problem, denn das Ziel muss man ja für sich selbst erst mal konkret und sauber definieren. Wenn man nur so ungefähr weiss wo man hin will, kann man keinen Code dafür schreiben, denn der hat ja immer ein konkretes Ergebnis.
Was mich hier jetzt verwirrt ist a) das es anscheinend für den Produktnamen auch verschiedene Möglichkeiten geben kann‽ und b) natürlich wieder die Schreibweise des Ergebnisses was weder Python noch JSON ist, man also raten muss was gemeint sein könnte.
Da könnte man doch einfach wieder Wörterbücher nehmen, mit den gleichen Schlüsseln, aber dann halt immer nur einen Wert der ganzen Alternativen.
Was mich hier jetzt verwirrt ist a) das es anscheinend für den Produktnamen auch verschiedene Möglichkeiten geben kann‽ und b) natürlich wieder die Schreibweise des Ergebnisses was weder Python noch JSON ist, man also raten muss was gemeint sein könnte.
Da könnte man doch einfach wieder Wörterbücher nehmen, mit den gleichen Schlüsseln, aber dann halt immer nur einen Wert der ganzen Alternativen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
- __blackjack__
- User
- Beiträge: 13006
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Namen und Werte sollte man mit `zip()` zusammenführen können:
Code: Alles auswählen
#!/usr/bin/env python3
from itertools import product
from pprint import pprint
def main():
properties = {
'Farbe': ['rot', 'blau'],
'Reifen': ['Dicke Reifen', 'normale Reifen'],
'Türen': [2, 3, 4, 5]
}
names = list(properties.keys())
result = [
dict(zip(names, values))
for values in product(*(properties[name] for name in names))
]
pprint(result)
if __name__ == '__main__':
main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
@__blackjack__: jetzt mußte ich doch etwas überlegen, warum `names` eigentlich nötig ist. Aber man sollte ja nicht voraussetzen, dass bei einem sich nicht verändernden Wörterbuch die Schlüssel immer in der gleichen Reihenfolge geliefert werden.
Hätte es dann vielleicht so geschrieben:
Hätte es dann vielleicht so geschrieben:
Code: Alles auswählen
names, values = zip(*properties.items())
result = [dict(zip(names, v)) for v in product(*values)]