Wbudowany itertools
moduł Pythona w rzeczywistości ma groupby
funkcję, ale w tym celu elementy do zgrupowania muszą najpierw zostać posortowane w taki sposób, aby elementy do zgrupowania były ciągłe na liście:
from operator import itemgetter
sortkeyfn = itemgetter(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)
Teraz dane wejściowe wyglądają następująco:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
zwraca sekwencję 2-krotek postaci (key, values_iterator)
. Chcemy przekształcić to w listę dykt, w których „typ” jest kluczem, a „pozycje” jest listą zerowych elementów krotek zwracanych przez wartość_iterator. Lubię to:
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)))
Teraz result
zawiera żądany dykt, zgodnie z pytaniem.
Możesz jednak rozważyć po prostu zrobienie z tego pojedynczego dyktu, kluczowanego według typu i każdej wartości zawierającej listę wartości. W obecnym formularzu, aby znaleźć wartości dla określonego typu, będziesz musiał iterować po liście, aby znaleźć dict zawierający pasujący klucz „type”, a następnie pobrać z niego element „items”. Jeśli używasz pojedynczego dyktowania zamiast listy jednopozycyjnych dykt, możesz znaleźć pozycje dla określonego typu za pomocą pojedynczego klucza wyszukiwania w głównym dyktowaniu. Używając groupby
, wyglądałoby to następująco:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
zawiera teraz ten dykt (jest podobny do pośredniego res
domyślnego słowa w odpowiedzi @ KennyTM):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Jeśli chcesz zredukować to do jednej linijki, możesz:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
lub korzystając z nowomodnego formularza ze zrozumieniem:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
gdzie ostatni element krotki to klucz, a pierwsze dwie jako wartość. Wynik powinien wyglądać następująco: wynik = [{typ: 'KAT', elementy: [('11013331', czerwony), ('9085267', niebieski)]}]