首页 > 解决方案 > 如何根据子列表中的值过滤 2 级列表?

问题描述

认为下面的列表是一个表,其中 sublist[0] 包含列标题。

data = [
            ['S1', 'S2 ', 'ELEMENT', 'C1', 'C2'], 
            ['X' ,  'X' , 'GRT'    ,  1,    4  ], 
            [''  ,  'X' , 'OIP'    ,  3,    2  ], 
            [''  ,  'X' , 'LKJ'    ,  2,    7  ], 
            ['X' ,  ''  , 'UBC'    ,  1,    0  ]
        ]
    

我正在尝试根据“列 S1”和“列 S2”中的值过滤列表。

我想得到:

像这样:

S1 = [
            ['ELEMENT', 'C1', 'C2'], 
            ['GRT',      1,    4  ], 
            ['UBC',      1,    0  ]
        ]       

S2 = [
            ['ELEMENT', 'C1', 'C2'], 
            ['GRT',      1,    4  ], 
            ['OIP',      3,    2  ], 
            ['LKJ',      2,    7  ]
        ]

下面我展示了到目前为止的代码,我在其中制作了源列表data的副本,然后检查哪个子列表在“列 S1”中没有“X”。我在新列表中获得了正确的内容S1,但我不知道为什么data要修改源列表并且我不能使用它来获取新列表S2

S1 = data
for sublist in S1[1:]:
    if sublist[0] != "X":
            s1.remove(sublist)

s2 = data
for sublist in S2[1:]:
    if sublist[1] != "X":
            s2.remove(sublist)


>>> data
[['S1', 'S2 ', 'ELEMENT', 'C1', 'C2'], ['X', 'X', 'GRT', 1, 4], ['X', '', 'UBC', 1, 0]]
>>> S1
[['S1', 'S2 ', 'ELEMENT', 'C1', 'C2'], ['X', 'X', 'GRT', 1, 4], ['X', '', 'UBC', 1, 0]]
>>> 

如何更好地获取列表S1S2?谢谢。

标签: python-3.xlistfilter

解决方案


您的问题是因为简单地将列表分配给新名称不会复制。

您也许可以通过执行使您的解决方案起作用

S1 = data[:]  # slicing makes a copy
S2 = data[:]

反而。


这是一个通用的解决方案:

def split_from_columns(ls, i_columns=(), indicator='X'):
    for i in i_columns:
        yield [
            [v for k, v in enumerate(sl) if k not in i_columns]
            for j, sl in enumerate(ls)
            if j == 0 or sl[i] == indicator
        ]

用法:

>>> S1, S2 = split_from_columns(data, i_columns=(0, 1))
>>> S1
[['ELEMENT', 'C1', 'C2'], ['GRT', 1, 4], ['UBC', 1, 0]]
>>> S2
[['ELEMENT', 'C1', 'C2'], ['GRT', 1, 4], ['OIP', 3, 2], ['LKJ', 2, 7]]

if j == 0部分确保我们始终复制标题。您可以更改i_columns以调整指标列的位置。


推荐阅读