Python eingebauten in itertools
Modul hat tatsächlich eine groupby
Funktion, die Sie verwenden können, aber die Elemente müssen zuerst so sortiert werden, gruppiert werden, dass die Elemente angrenzen, in der Liste gruppiert werden:
sortkeyfn = key=lambda s:s[1]
input = [('11013331', 'KAT'), ('9085267', 'NOT'), ('5238761', 'ETH'),
('5349618', 'ETH'), ('11788544', 'NOT'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('9843236', 'KAT'), ('5594916', 'ETH'), ('1550003', 'ETH')]
input.sort(key=sortkeyfn)
Jetzt sieht Eingang wie:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
eine Folge von 2-Tupeln zurückgibt, von der Form (key, values_iterator)
. Wir wollen dies in eine Liste von Dicts umwandeln, in der der "Typ" der Schlüssel ist, und "Items" ist eine Liste der 0. Elemente der Tupel, die von values_iterator zurückgegeben werden. Wie folgt aus:
from itertools import groupby
result = []
for key,valuesiter in groupby(input, key=sortkeyfn):
result.append(dict(type=key, items=list(v[0] for v in valuesiter)))
Jetzt result
enthält gewünschten dict, wie in Ihrer Frage angegeben.
Sie könnten jedoch in Erwägung ziehen, nur ein einziges Diktat daraus zu erstellen, das nach Typ und jedem Wert mit der Werteliste codiert ist. Um in Ihrem aktuellen Formular die Werte für einen bestimmten Typ zu finden, müssen Sie über die Liste iterieren, um das dict zu finden, das den passenden 'type' Schlüssel enthält, und dann das Element 'items' daraus abfragen. Wenn Sie ein einzelnes Diktat anstelle einer Liste von 1-Item-Dicts verwenden, können Sie die Items für einen bestimmten Typ mit einer einzigen Schlüsselsuche im Master-Diktat suchen.Mit groupby
, würde dies wie folgt aussehen:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
jetzt dieses dict enthält (dies ist ähnlich dem Zwischen res
defaultdict in @ KennyTM Antwort):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Wenn Sie wollen, dass diese zu reduzieren, ein Einzeiler, können Sie:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
oder das neumodische dict Verständnis Formular:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
einstellen, wie dies, wenn die Eingangstupel einen Schlüssel und zwei oder mehr Werte hat getan werden kann, wie folgt aus: '[(‚11013331‘,‚rot‘ , 'KAT'), ('9085267', 'blue' 'KAT')] 'wo das letzte Element des Tupels der Schlüssel ist und die ersten beiden als Wert. Ergebnis sollte so sein: result = [{ Typ: 'KAT', Elemente: [('11013331', rot), ('9085267', blau)]}] – user1144616