У меня есть следующий список списков

listA = [
    ["4YBB|1|AA|A|262", "4YBB|1|AA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|A|263", "tSH", 'empty', 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|C|264", "ntSH", 'empty', "5BPh", 'empty'], 
    ["4YBB|1|AA|G|259", "4YBB|1|AA|C|267", "cWW", 'empty', 'empty', 'empty'], 
    ["4WOI|1|DA|A|262", "4WOI|1|DA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4WOI|1|DA|C|264", "4WOI|1|DA|G|265", 'empty', "s35", 'empty', 'empty']
    ]

Я хотел бы сгруппировать их на основе идентификаторов из другого списка, и они должны быть упорядочены так же, как элементы в списке идентификаторов:

identifiers = ["4YBB|1|AA", "4WOI|1|DA"]

Как видите, идентификаторы являются подмножеством строковых элементов 1 и 2 внутреннего списка. Идентификаторы всегда будут одинаковыми для элементов 1 и 2 внутреннего списка. Желаемый результат выглядит следующим образом:

desiredoutput = [
              [
                ["4YBB|1|AA|A|262", "4YBB|1|AA|A|263", 'empty', "s35", 'empty', 'empty'], 
                ["4YBB|1|AA|U|261", "4YBB|1|AA|A|263", "tSH", 'empty', 'empty', 'empty'], 
                ["4YBB|1|AA|U|261", "4YBB|1|AA|C|264", "ntSH", 'empty', "5BPh", 'empty'], 
                ["4YBB|1|AA|G|259", "4YBB|1|AA|C|267", "cWW", 'empty', 'empty', 'empty'],
              ],
              [ 
                ["4WOI|1|DA|A|262", "4WOI|1|DA|A|263", 'empty', "s35", 'empty', 'empty'], 
                ["4WOI|1|DA|C|264", "4WOI|1|DA|G|265", 'empty', "s35", 'empty', 'empty']
              ]
            ]

Как я могу добиться этого, используя метод itertools groupby или любые другие методы?

2
TheEmperor 1 Июл 2019 в 12:45

3 ответа

Лучший ответ

Это один подход с использованием модуля collections.

< Сильный > Пример:

from collections import defaultdict, OrderedDict

listA = [
    ["4YBB|1|AA|A|262", "4YBB|1|AA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|A|263", "tSH", 'empty', 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|C|264", "ntSH", 'empty', "5BPh", 'empty'], 
    ["4YBB|1|AA|G|259", "4YBB|1|AA|C|267", "cWW", 'empty', 'empty', 'empty'], 
    ["4WOI|1|DA|A|262", "4WOI|1|DA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4WOI|1|DA|C|264", "4WOI|1|DA|G|265", 'empty', "s35", 'empty', 'empty']
    ]
identifiers = ["4YBB|1|AA", "4WOI|1|DA"]
result = defaultdict(list)

for i in listA:
    key = i[0].rsplit('|', 2)[0]               #Get Key
    if key in identifiers:                     #Check in identifiers 
        result[key].append(i)                  #Group

result = OrderedDict(sorted(result.items(), key=lambda x: identifiers.index(x[0]))) #Sort base on identifiers 
print(result.values())

< Сильный > Вывод :

[[['4YBB|1|AA|A|262', '4YBB|1|AA|A|263', 'empty', 's35', 'empty', 'empty'],
  ['4YBB|1|AA|U|261', '4YBB|1|AA|A|263', 'tSH', 'empty', 'empty', 'empty'],
  ['4YBB|1|AA|U|261', '4YBB|1|AA|C|264', 'ntSH', 'empty', '5BPh', 'empty'],
  ['4YBB|1|AA|G|259', '4YBB|1|AA|C|267', 'cWW', 'empty', 'empty', 'empty']],
 [['4WOI|1|DA|A|262', '4WOI|1|DA|A|263', 'empty', 's35', 'empty', 'empty'],
  ['4WOI|1|DA|C|264', '4WOI|1|DA|G|265', 'empty', 's35', 'empty', 'empty']]]

Просто к вашему сведению. Используя itertools.groupby

from itertools import groupby

listA = [
    ["4YBB|1|AA|A|262", "4YBB|1|AA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|A|263", "tSH", 'empty', 'empty', 'empty'], 
    ["4YBB|1|AA|U|261", "4YBB|1|AA|C|264", "ntSH", 'empty', "5BPh", 'empty'], 
    ["4YBB|1|AA|G|259", "4YBB|1|AA|C|267", "cWW", 'empty', 'empty', 'empty'], 
    ["4WOI|1|DA|A|262", "4WOI|1|DA|A|263", 'empty', "s35", 'empty', 'empty'], 
    ["4WOI|1|DA|C|264", "4WOI|1|DA|G|265", 'empty', "s35", 'empty', 'empty']
    ]
identifiers = ["4YBB|1|AA", "4WOI|1|DA"]

result = [list(value) for k, value in groupby(sorted(listA, key=lambda x: x[0].rsplit('|', 2)[0]), lambda x: x[0].rsplit('|', 2)[0]) if k in identifiers]
print(result)
0
Rakesh 1 Июл 2019 в 10:10

Вот способ сделать это:

output = []
inter = []
prev_id = listA[0][0]
for element in listA:
    if element[0]==prev_id:
        inter.append(element)
    else:
        output.append(inter)
        prev_id = element[0]
        inter=[element]

Выход:

[[['4YBB|1|AA|A|262', '4YBB|1|AA|A|263', 'empty', 's35', 'empty', 'empty']],
 [['4YBB|1|AA|U|261', '4YBB|1|AA|A|263', 'tSH', 'empty', 'empty', 'empty'],
  ['4YBB|1|AA|U|261', '4YBB|1|AA|C|264', 'ntSH', 'empty', '5BPh', 'empty']],
 [['4YBB|1|AA|G|259', '4YBB|1|AA|C|267', 'cWW', 'empty', 'empty', 'empty']],
 [['4WOI|1|DA|A|262', '4WOI|1|DA|A|263', 'empty', 's35', 'empty', 'empty']]]
0
vlemaistre 1 Июл 2019 в 09:54

Поскольку идентификаторы всегда будут одинаковыми для элементов 1 и 2 внутреннего списка. - мы можем сгруппировать нужные фрагменты с помощью defaultdict:

from collections import defaultdict
import pprint

listA = [
    ["4YBB|1|AA|A|262", "4YBB|1|AA|A|263", 'empty', "s35", 'empty', 'empty'],
    ["4YBB|1|AA|U|261", "4YBB|1|AA|A|263", "tSH", 'empty', 'empty', 'empty'],
    ["4YBB|1|AA|U|261", "4YBB|1|AA|C|264", "ntSH", 'empty', "5BPh", 'empty'],
    ["4YBB|1|AA|G|259", "4YBB|1|AA|C|267", "cWW", 'empty', 'empty', 'empty'],
    ["4WOI|1|DA|A|262", "4WOI|1|DA|A|263", 'empty', "s35", 'empty', 'empty'],
    ["4WOI|1|DA|C|264", "4WOI|1|DA|G|265", 'empty', "s35", 'empty', 'empty']
    ]

groups = defaultdict(list)
for sub_l in listA:
    groups[sub_l[0][:10]].append(sub_l)

result = list(groups.values())
pprint.pprint(result)

Выход:

[[['4YBB|1|AA|A|262', '4YBB|1|AA|A|263', 'empty', 's35', 'empty', 'empty'],
  ['4YBB|1|AA|U|261', '4YBB|1|AA|A|263', 'tSH', 'empty', 'empty', 'empty'],
  ['4YBB|1|AA|U|261', '4YBB|1|AA|C|264', 'ntSH', 'empty', '5BPh', 'empty'],
  ['4YBB|1|AA|G|259', '4YBB|1|AA|C|267', 'cWW', 'empty', 'empty', 'empty']],
 [['4WOI|1|DA|A|262', '4WOI|1|DA|A|263', 'empty', 's35', 'empty', 'empty'],
  ['4WOI|1|DA|C|264', '4WOI|1|DA|G|265', 'empty', 's35', 'empty', 'empty']]]
0
RomanPerekhrest 1 Июл 2019 в 09:55