Как переклассифицировать список кортежей по первому элементу в Python? - PullRequest
0 голосов
/ 20 февраля 2020

Используя Python3 .x, у меня есть список кортежей следующим образом (где первый элемент является целым числом или строкой):

tuple_list = [(1, 'AA', 515), (1, 'BBT', 101), 
                  (1, 'CZF', 20), (2, 'TYZ', 8341), (2, 'ONR', 11)]

В этом примере некоторые из кортежей начинаются с 1 и другие с 2. Каждый был внесен в отдельный список.

Я бы хотел, чтобы способ "классифицировать" кортежи с одинаковым первым элементом в отдельные списки.

В данном случае желаемым решением является список списков:

[[(1, 'AA', 515), (1, 'BBT', 101), (1, 'CZF', 20)], 
        [(2, 'TYZ', 8341), (2, 'ONR', 11)]]

Это можно сделать, выполнив итерацию и проверив, существует ли сначала список для каждого (уникального) элемент, но это будет вычислительно дорого для больших списков с более «уникальными» первыми элементами, чем просто 1 и 2.

Как можно было бы сделать это быстро / эффективно?

Ответы [ 2 ]

3 голосов
/ 20 февраля 2020

Использование itertools.groupby. В сочетании с operator.itemgetter для эффективного поиска / нарезки.

from itertools import groupby
from operator import itemgetter

tuple_list = [(1, 'AA', 515), (1, 'BBT', 101), (1, 'CZF', 20), (2, 'TYZ', 8341), (2, 'ONR', 11)]

get_first = itemgetter(0)
result = [list(g) for k, g in groupby(sorted(tuple_list, key=get_first), get_first)]

Результат:

[[(1, 'AA', 515), (1, 'BBT', 101), (1, 'CZF', 20)], [(2, 'TYZ', 8341), (2, 'ONR', 11)]]

Или используйте collections.defaultdict

from collections import defaultdict

d = defaultdict(list)

for t in tuple_list:
    d[t[0]].append(t)

result = list(d.values())

Результат:

[[(1, 'AA', 515), (1, 'BBT', 101), (1, 'CZF', 20)], [(2, 'TYZ', 8341), (2, 'ONR', 11)]]
1 голос
/ 20 февраля 2020

Один из способов - использовать defaultdict и сохранить первый элемент в качестве индекса, а затем сгруппировать их, как показано ниже:

from collections import defaultdict

tuple_list = [(1, 'AA', 515), (1, 'BBT', 101),
                  (1, 'CZF', 20), (2, 'TYZ', 8341), (2, 'ONR', 11)]

dct = defaultdict(list)
for l in tuple_list:
    dct[l[0]].append(l)

print(sorted(dct.values(), key=lambda l: l[0][0]))

>>> [[(1, 'AA', 515), (1, 'BBT', 101), (1, 'CZF', 20)], [(2, 'TYZ', 8341), (2, 'ONR', 11)]]
...