itertools
Modul built-in Python sebenarnya memiliki groupby
fungsi, tetapi untuk itu elemen yang akan dikelompokkan harus diurutkan terlebih dahulu sehingga elemen yang akan dikelompokkan bersebelahan dalam daftar:
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)
Sekarang masukan terlihat seperti:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
mengembalikan urutan 2-tupel, dari bentuk (key, values_iterator)
. Apa yang kita inginkan adalah mengubahnya menjadi daftar dicts di mana 'type' adalah kuncinya, dan 'items' adalah daftar elemen ke-0 dari tupel yang dikembalikan oleh values_iterator. Seperti ini:
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)))
Sekarang result
berisi dikt yang Anda inginkan, seperti yang dinyatakan dalam pertanyaan Anda.
Anda dapat mempertimbangkan, meskipun, hanya membuat satu dikt dari ini, dikunci menurut jenis, dan setiap nilai yang berisi daftar nilai. Dalam formulir Anda saat ini, untuk menemukan nilai untuk tipe tertentu, Anda harus mengulang daftar untuk menemukan dikt yang berisi kunci 'tipe' yang cocok, dan kemudian mendapatkan elemen 'item' darinya. Jika Anda menggunakan satu dikt dan bukan daftar dict 1-item, Anda dapat menemukan item untuk tipe tertentu dengan pencarian kunci tunggal ke dikt utama. Menggunakan groupby
, ini akan terlihat seperti:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
sekarang berisi dict ini (ini mirip dengan res
defaultdict menengah dalam jawaban @ KennyTM):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(Jika Anda ingin mengurangi ini menjadi satu baris, Anda dapat:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
atau menggunakan bentuk dikt-pemahaman bermodel baru:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
mana elemen terakhir tupel adalah kunci dan dua yang pertama sebagai nilai. Hasilnya harus seperti ini: result = [{type: 'KAT', items: [('11013331', red), ('9085267', blue)]}]