Python 中具有多个循环的复杂列表理解

loa*_*oza 2 python lambda list-comprehension

我目前正在做一些理解列表,并在增加其中的循环数量时遇到问题。到目前为止我的代码如下:

selected_sheet_names = []
selected_sheet_names.append([x for x in sheet_names if x.endswith("b1")])
selected_sheet_names.append([x for x in sheet_names if x.endswith("b2")])
selected_sheet_names.append([x for x in sheet_names if x.endswith("b3")])
Run Code Online (Sandbox Code Playgroud)

sheet_nameslist 包含不同的字符串,所有字符串均以b1, b2, 或结尾b3。如果您想在代码中检查它们:

sheet_names = ['0.5C_1_b1', '0.5C_2_b1', '1C_1_b1', '1C_2_b1', '1C_3_b1', '1C_4_b1', '1C_5_b1', 
'0.11C_1_b2', '0.57C_1_b2', '1.14C_1_b2', '1.14C_2_b2', '1.14C_3_b2', '1.14C_4_b2', '1.14C_5_b2', 
'1.14C_6_b2', '1.14C_7_b2', '1.14C_8_b2', '1C_1_b3', '1C_2_b3', '1C_3_b3', '1C_4_b3', '1C_5_b3', 
'1C_6_b3', '1C_7_b3', '1C_8_b3']

Run Code Online (Sandbox Code Playgroud)

如果我想要print(selected_sheet_names)结果如下:

[
    ['0.5C_1_b1', '0.5C_2_b1', '1C_1_b1', '1C_2_b1', '1C_3_b1', '1C_4_b1', '1C_5_b1'], 
    ['0.11C_1_b2', '0.57C_1_b2', '1.14C_1_b2', '1.14C_2_b2', '1.14C_3_b2', '1.14C_4_b2', '1.14C_5_b2', '1.14C_6_b2', '1.14C_7_b2', '1.14C_8_b2'], 
    ['1C_1_b3', '1C_2_b3', '1C_3_b3', '1C_4_b3', '1C_5_b3', '1C_6_b3', '1C_7_b3', '1C_8_b3']
]
Run Code Online (Sandbox Code Playgroud)

完全符合我的预期,但如果我想要x.endswith(some_string)像第一个代码块那样有更多内容,代码就会变得太大,因此,我认为我应该尝试将重复selected_sheet_names.append([x for x in sheet_names if x.endswith(some_string)])多次的 更改为其他更复杂的列表理解,这可以迭代some_list并做同样的事情。

some_list = ["b1", "b2", "b3" ... ]
Run Code Online (Sandbox Code Playgroud)

有人可以给我推荐一些东西吗?

编辑1:我知道我可以用 for 循环来实现它,但在这个例子中,如果可能的话,我对理解实现列表特别感兴趣。for 循环可以如下所示:

selected_sheet_names = []
for ending in some_list:
    selected_sheet_names.append([x for x in sheet_names if x.endswith(ending)])
Run Code Online (Sandbox Code Playgroud)

编辑2(感谢佩德罗·马亚):

如果数据是连续的(但不是我的情况),您可以使用:

from itertools import groupby

selected_sheet_names = [list(l[1]) for l in groupby(sheet_names, lambda x: x[-2:])]
Run Code Online (Sandbox Code Playgroud)

我很遗憾我向您展示了一个连续的列表。如果您的数据不连续,输出可能如下所示:

[
    ['0.11C_1_b2'], 
    ['0.5C_1_b1'], 
    ['0.57C_1_b2'], 
    ['0.5C_2_b1', '1C_1_b1', '1C_2_b1', '1C_3_b1', '1C_4_b1', '1C_5_b1'], 
    ['1.14C_1_b2', '1.14C_2_b2', '1.14C_3_b2', '1.14C_4_b2', '1.14C_5_b2', '1.14C_6_b2', '1.14C_7_b2', '1.14C_8_b2'], 
    ['1C_1_b3', '1C_2_b3', '1C_3_b3', '1C_4_b3', '1C_5_b3', '1C_6_b3', '1C_7_b3', '1C_8_b3']
]
Run Code Online (Sandbox Code Playgroud)

但是,如果您的数据是连续的,则此方法似乎更好

谢谢你们的回复!

Sha*_*ger 6

与您建议的形式匹配的简单嵌套 listcomp 将循环遍历匿名tuple字符串以检查:

selected_sheet_names = [[x for x in sheet_names if x.endswith(some_string)]
                        for some_string in ("b1", "b2", "b3")]
Run Code Online (Sandbox Code Playgroud)

如果您some_list从其他地方获取,或者它太长而无法舒适地定义内联,则可以将匿名替换tuplesome_list(如果已经定义)。