Seite 1 von 1
Liste ausdünnen
Verfasst: Freitag 10. Juli 2020, 19:08
von snowflake
Guten Abend zusammen,
ich habe folgende Liste und möchte die Liste insoweit ausdünnen, dass gleiche "Unterlisten" zusammengefasst werden.
Code: Alles auswählen
liste = [[1, 'SIM20', 'BBU-IM', '2Hj'], [1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
Aus folgenden beiden "Unterlisten" wird dann nur noch eine "Unterliste":
Code: Alles auswählen
[1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW']
zusammengefasst
Die ausgedünnte Liste sollte dann als Ergebnis so aussehen:
Code: Alles auswählen
liste = [[1, 'SIM20', 'BBU-IM', '2Hj'], [2, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
Die Wertigkeit von 1 und 1 wurde mit 2 angegeben (addiert).
Die Liste beinhaltet viel mehr Unterlisten, die ich hier der Einfachkeithalber nicht dargestellt habe. Kann mir jemand weiterhelfen? Ich finde keinen Anfang.
Viele Grüße
snowflake
Re: Liste ausdünnen
Verfasst: Freitag 10. Juli 2020, 19:59
von nezzcarth
Es gibt da vermutlich mehrere Lösungen. Meine funktioniert mit Dictionaries. Die Schlüssel von Dictionaries sind einmalig und (in neueren Python-Versionen) auch nach der Eingabereihenfolge sortiert. Wenn du deine inneren Listen (in Tupel konvertiert) als Schlüssel nimmst, kannst du dir die Zahl, die bei Wiederholungen aufsummiert werden soll, als Wert merken (die setdefault Methode von Dictionaries ist dafür hilfreich). Aus dem Dictionary kannst du dir dann deine Liste wieder zusammenbauen.
Ergebnis:
Code: Alles auswählen
In [1]: items = [[1, 'SIM20', 'BBU-IM', '2Hj'], [1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
...
In [5]: new_items
Out[5]:
[[1, 'SIM20', 'BBU-IM', '2Hj'],
[2, 'SIM18', 'BBU-IM', '02uW'],
[2, 'SIM18', 'BBU-IM', None]]
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 00:00
von Caskuda
Mit dem Counter - Dictionary:
Code: Alles auswählen
from collections import Counter
liste = [[1, 'SIM20', 'BBU-IM', '2Hj'], [1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
#print(liste)
myCount = Counter()
for item in liste:
n, *vals = item
vals = tuple(vals)
myCount[vals] += n
#print(myCount)
liste = [[myCount.get(vals)] + list(vals) for vals in myCount]
print(liste)
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 07:13
von snowflake
Guten Morgen Caskuda,
vielen Dank für Deinen Lösungsvorschlag (danke auch an nezzcarth). Auf diesen Ansatz wäre ich im Leben nicht gekommen. Er funktioniert hervorragend.
Was ich aber nicht verstehe ist folgende Stelle:
Warum wird hier die Anzahl an n und der Rest an *vals übergeben?
Nochmals vielen Dank.
snowflake
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 07:45
von __deets__
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 08:05
von snowflake
Ok, vielen Dank. Mit dem Link ist es jetzt klar.
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 08:41
von nezzcarth
Hier meine Lösung mit setdefault:
Code: Alles auswählen
In [1]: items = [[1, 'SIM20', 'BBU-IM', '2Hj'], [1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
In [2]: result = dict()
In [3]: for item in items:
...: item = tuple(item)
...: result.setdefault(item, 0)
...: result[item] += item[0]
...:
In [4]: new_items = [[value, *key[1:]] for key, value in result.items()]
In [5]: new_items
Out[5]:
[[1, 'SIM20', 'BBU-IM', '2Hj'],
[2, 'SIM18', 'BBU-IM', '02uW'],
[2, 'SIM18', 'BBU-IM', None]]
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 09:56
von Sirius3
Von Counter wird fast nichts benutzt und setdefault kann man auch eleganter per defaultdict lösen. Variablennamen werden komplett klein geschrieben. Sie bestehen nicht aus Abkürzungen oder sinnfreien Präfixen wie my.
Code: Alles auswählen
from collections import defaultdict
liste = [[1, 'SIM20', 'BBU-IM', '2Hj'], [1, 'SIM18', 'BBU-IM', '02uW'], [1, 'SIM18', 'BBU-IM', '02uW'], [2, 'SIM18', 'BBU-IM', None]]
counted_whatever = defaultdict(int)
for count, *whatever in liste:
counted_whatever[tuple(whatever)] += count
liste = [[count] + list(whatever) for count, whatever in counted_whatever.items()]
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 10:00
von __blackjack__
Anregung für die letzte Zeile (ungetestet):
Code: Alles auswählen
liste = [[count, *whatever] for count, whatever in counted_whatever.items()]
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 10:39
von nezzcarth
Sirius3 hat geschrieben: Samstag 11. Juli 2020, 09:56
… setdefault kann man auch eleganter per defaultdict lösen.
Interessant, dass du das sagst. Ich habe früher immer defaultdict für so etwas verwendet, in neuem Code nehme ich aber nach Möglichkeit setdefault und refactore teilweise auch älteren Code in der Hinsicht. Aus meiner Sicht macht defaultdict mitunter mehr Probleme, als es löst (zum Beispiel dadurch, dass jeder Schlüsselzugriff gleich einen Schlüssel erzeugt). Hier ist das evtl. nicht so relevant.
Re: Liste ausdünnen
Verfasst: Samstag 11. Juli 2020, 13:54
von Sirius3
Das sind ja meist unterschiedliche Anwendungsfälle. Wörterbücher, auf die man mit konkreten Schlüsseln zugreift, und solchen, die zum Sammeln von unbekannten Daten da sind. Im ersten Fall würde ich normalerweise auch kein defaultdict benutzen.