Angenommen, ich habe eine Reihe von Datenpaaren, wobei Index 0 der Wert und Index 1 der Typ ist:
input = [
('11013331', 'KAT'),
('9085267', 'NOT'),
('5238761', 'ETH'),
('5349618', 'ETH'),
('11788544', 'NOT'),
('962142', 'ETH'),
('7795297', 'ETH'),
('7341464', 'ETH'),
('9843236', 'KAT'),
('5594916', 'ETH'),
('1550003', 'ETH')
]
Ich möchte sie nach ihrem Typ (nach der ersten indizierten Zeichenfolge) als solche gruppieren:
result = [
{
type:'KAT',
items: ['11013331', '9843236']
},
{
type:'NOT',
items: ['9085267', '11788544']
},
{
type:'ETH',
items: ['5238761', '962142', '7795297', '7341464', '5594916', '1550003']
}
]
Wie kann ich dies effizient erreichen?
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
folgt : wobei das letzte Element des Tupels der Schlüssel und die ersten beiden als Wert sind. Das Ergebnis sollte folgendermaßen aussehen: result = [{type: 'KAT', items: [('11013331', red), ('9085267', blue)]}]from operator import itemgetter
d= {}; for k,v in input: d.setdefault(k, []).append(v)
Das in Python integrierte
itertools
Modul hat tatsächlich einegroupby
Funktion, aber dafür müssen die zu gruppierenden Elemente zuerst so sortiert werden, dass die zu gruppierenden Elemente in der Liste zusammenhängend sind:Jetzt sieht die Eingabe so aus:
groupby
Gibt eine Folge von 2 Tupeln der Form zurück(key, values_iterator)
. Was wir wollen, ist, dies in eine Liste von Diktaten umzuwandeln, wobei der 'Typ' der Schlüssel ist und 'Elemente' eine Liste der 0-ten Elemente der Tupel ist, die vom values_iterator zurückgegeben werden. So was:result
Enthält jetzt Ihr gewünschtes Diktat, wie in Ihrer Frage angegeben.Sie könnten jedoch in Betracht ziehen, daraus nur ein einziges Diktat zu machen, das nach Typ und jedem Wert, der die Werteliste enthält, verschlüsselt ist. Um in Ihrem aktuellen Formular die Werte für einen bestimmten Typ zu ermitteln, müssen Sie die Liste durchlaufen, um das Diktat mit dem passenden Schlüssel "Typ" zu finden, und dann das Element "Elemente" daraus abrufen. Wenn Sie ein einzelnes Diktat anstelle einer Liste von 1-Element-Diktaten verwenden, können Sie die Elemente für einen bestimmten Typ mit einer einzigen verschlüsselten Suche im Master-Diktat finden. Mit
groupby
würde dies folgendermaßen aussehen:result
enthält jetzt dieses Diktat (dies ähnelt dem Zwischen-res
Standarddiktat in der Antwort von @ KennyTM):(Wenn Sie dies auf einen Einzeiler reduzieren möchten, können Sie:
oder unter Verwendung der neuen Form des Diktverständnisses:
quelle
Ich mochte auch Pandas einfach Gruppierung . Es ist leistungsstark, einfach und am besten für große Datenmengen geeignet
result = pandas.DataFrame(input).groupby(1).groups
quelle
Diese Antwort ähnelt der Antwort von @ PaulMcG erfordert jedoch kein Sortieren der Eingabe.
Für diejenigen, die sich mit funktionaler Programmierung beschäftigen,
groupBy
kann in einer Zeile geschrieben werden (ohne Importe!), Und im Gegensatzitertools.groupby
dazu muss die Eingabe nicht sortiert werden:(Der Grund für die
... or grp
in derlambda
ist , dass dies fürreduce()
zu arbeiten, dielambda
Bedürfnisse seines erstes Argument zurück, weillist.append()
immer wiederNone
dieor
wird immer wieder zurückkehrengrp
. Dh es ein Hack ist Einschränkung zu umgehen , Pythons , dass eine Lambda nur einen einzigen Ausdruck auswerten kann.)Dies gibt ein Diktat zurück, dessen Schlüssel durch Auswerten der angegebenen Funktion gefunden werden und dessen Werte eine Liste der Originalelemente in der ursprünglichen Reihenfolge sind. Wenn Sie für das Beispiel des OP dies so nennen,
groupBy(lambda pair: pair[1], input)
wird dieses Dikt zurückgegeben:Und gemäß der Antwort von @ PaulMcG kann das angeforderte Format des OP gefunden werden, indem es in ein Listenverständnis eingeschlossen wird. Das wird es also tun:
quelle
Die folgende Funktion gruppiert schnell ( keine Sortierung erforderlich) Tupel beliebiger Länge nach einem Schlüssel mit einem Index:
Im Fall Ihrer Frage ist der Index des Schlüssels, nach dem Sie gruppieren möchten, 1, daher:
gibt
Dies ist nicht genau die Ausgabe, nach der Sie gefragt haben, die aber genauso gut Ihren Anforderungen entspricht.
quelle
quelle