在基于子列表过滤列表时,如何避免硬编码?

2024-05-15 22:20:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下列表,并且我正在删除所有不包含sl[0]sl[1]子列表的列表:

l = [
 ['s1', 's5', 's6', 's8', 's10', 's5', 's15', 's23'],
 ['s1', 's5', 's8', 's10', 's5', 's6', 's8', 's15', 's23'],
 ['s1', 's5', 's6', 's10', 's14', 's15', 's23']
]
sl = [['s5','s6','s8'],['s15', 's23']]

此代码为2个子列表sl[0]sl[1]硬编码:

list(filter(lambda l : not(set(sl[0]+sl[1])-set(l)), l))

如何使此代码更灵活?如果sl包含5个或10个或任何其他数量的子列表怎么办


Tags: 代码编码列表lists6setsls5
2条回答

您可以使用more-itertools包来实现这一点。您需要在l的每个元素中检查len(sl[i])的每个子序列。这将是缓慢的,但可行的

我还创建了一个使用partial的工厂函数,这样您就可以随意插入sl的内容。这与filter的使用保持一致

from more_itertools import windowed
from functools import partial

def ordered_check(x, sub):
    s = tuple(sub)
    for y in windowed(x, len(sub)):
        if s == y:
            return True
    return False

def ordered_check_all(x, subs):
    return all(ordered_check(x, sub) for sub in subs)

def check_factory(subs):
    return partial(ordered_check_all, subs=subs)

list(filter(check_factory(sl), l))
# returns
[['s1', 's5', 's6', 's8', 's10', 's5', 's15', 's23'],
 ['s1', 's5', 's8', 's10', 's5', 's6', 's8', 's15', 's23'],
 ['s1', 's5', 's6', 's10', 's14', 's15', 's23']]

我很难读懂你的代码:

list(filter(lambda l : not(set(sl[0]+sl[1])-set(l)), l))

首先连接s1[0]sl[1]

['s5','s6','s8'] + ['s15', 's23']
becomes
['s5','s6','s8', 's15', 's23']

然后从sl[0]+sl[1]….set(sl[0]+sl[1])建立一个集合:

{'s5','s6','s8', 's15', 's23'}

然后从结果中减去set(l)。这甚至行不通,因为l是一个列表列表。字符串列表可以转换为一个集合,因为集合的元素可以是字符串。但是,列表不能是集合的元素


相关问题 更多 >