使用另一个列表中的字符串在列表列表中对元素进行分组

时间:2019-07-01 09:45:25

标签: python list-comprehension itertools

我有以下列表列表

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方法或任何其他方法来实现这一目标?

3 个答案:

答案 0 :(得分:0)

这是使用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)

答案 1 :(得分:0)

这是一种实现方法:

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']]]

答案 2 :(得分:0)

内部列表的元素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']]]