Listenin İçindeki Listeleri Kategorize Etme

Elimdeki listenin içinde bulunan listeleri birinci elemanlarına göre kategorize etmek istiyordum ve yaptım da. Ama biraz düzensiz ve saçma geldi yazdığım kod. Bunu nasıl daha kısa veya düzenli yazabilirim.

l = [(1, 49, 0), (0, 29, 205), (2, 253, 23), (1, 188, 46), (2, 164, 199)]

"""
İSTENEN ÇIKTI :
[
    (0, [(0, 29, 205)]),
    (1, [(1, 49, 0), (1, 188, 46)]),
    (2, [(2, 253, 23), (2, 164, 199)])
]
"""

categorized = {i : [] for i in {j[0] for j in l}}
for i in l:
    categorized[i[0]].append(i)
categorized = list(categorized.items())

"""
ÇIKTI :
[
    (0, [(0, 29, 205)]),
    (1, [(1, 49, 0), (1, 188, 46)]),
    (2, [(2, 253, 23), (2, 164, 199)]),
]
(PROGRAM DOĞRU ÇALIŞIYOR)
"""

>>> pprint.pprint([(i, [x for x in l if x[0] == i]) for i in {x[0] for x in l}])
[(0, [(0, 29, 205)]),
 (1, [(1, 49, 0), (1, 188, 46)]),
 (2, [(2, 253, 23), (2, 164, 199)])]

Listeyi iki kere okumak istemezsen indisleri geldikleri gibi yaratabilir veya collections.defaultdict(lambda: []) kullanabilirsin.

Fold olarak da yazdim ama dict'in + operatoru olmadigi icin cirkin oldu:

categorized = functools.reduce(lambda il, x: collections.defaultdict(lambda: [], {**il, **{x[0]: il[x[0]] + [x]}}), l, collections.defaultdict(lambda: []))

Bu da benden olsun:

l = [(1, 49, 0), (0, 29, 205), (2, 253, 23), (1, 188, 46), (2, 164, 199)]

f = lambda x: [
    (k, v) for k, v in {
        i[0]: [*filter(lambda j: j[0] == i[0], sorted(x))]
        for i in sorted(x)
    }.items()
]

print(f(l))

Çıktı:

[
    (0, [(0, 29, 205)]), 
    (1, [(1, 49, 0), (1, 188, 46)]), 
    (2, [(2, 164, 199), (2, 253, 23)])
]