itertools
โมดูลในตัวของ Python มีgroupby
ฟังก์ชัน แต่สำหรับองค์ประกอบที่จะจัดกลุ่มจะต้องเรียงลำดับก่อนเพื่อให้องค์ประกอบที่จะจัดกลุ่มนั้นอยู่ติดกันในรายการ:
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)
ตอนนี้การป้อนข้อมูลดูเหมือนว่า:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
ผลตอบแทนที่ได้ลำดับ 2 (key, values_iterator)
อันดับหนึ่งของรูปแบบ สิ่งที่เราต้องการคือเปลี่ยนสิ่งนี้ให้เป็นรายการของคำสั่งโดยที่ 'type' เป็นคีย์และ 'items' คือรายการขององค์ประกอบที่ 0 ของ tuples ที่ส่งคืนโดย values_iterator แบบนี้:
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)))
ตอนนี้result
มีคำสั่งที่คุณต้องการตามที่ระบุไว้ในคำถามของคุณ
คุณอาจพิจารณาเพียงแค่สร้างคำสั่งเดียวจากสิ่งนี้โดยป้อนตามประเภทและแต่ละค่าที่มีรายการค่า ในรูปแบบปัจจุบันของคุณในการค้นหาค่าสำหรับประเภทใดประเภทหนึ่งคุณจะต้องวนซ้ำในรายการเพื่อค้นหาคำสั่งที่มีคีย์ 'type' ที่ตรงกันจากนั้นจึงรับองค์ประกอบ 'items' จากมัน หากคุณใช้คำสั่งเดียวแทนรายการของคำสั่ง 1 รายการคุณสามารถค้นหารายการสำหรับประเภทใดประเภทหนึ่งได้ด้วยการค้นหาคีย์เดียวในคำสั่งต้นแบบ เมื่อใช้groupby
สิ่งนี้จะมีลักษณะดังนี้:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
ตอนนี้มีคำสั่งนี้ (ซึ่งคล้ายกับres
defaultdict ระดับกลางในคำตอบของ @ Kenny ™):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(หากคุณต้องการลดสิ่งนี้เป็นซับเดียวคุณสามารถ:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
หรือใช้แบบฟอร์มความเข้าใจแบบเขียนตามคำบอกแบบใหม่:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
โดยที่องค์ประกอบสุดท้ายของทูเปิลคือคีย์และสองตัวแรกเป็นค่า ผลลัพธ์ควรเป็นดังนี้ result = [{type: 'KAT', items: [('11013331', red), ('9085267', blue)]}]