用Python检查列表元素是否是另一个列表中的子元素

2024-06-08 13:25:55 发布

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

鉴于以下数据:

a = ["onee", "two", "three"]
b = ["one", "four"]

我想做一些测试,例如:

[True if x in a else False for x in b]

归来

[True, False]

而不是

[False, False]

所以对于listb中的每个元素,我想看看它是否是lista中任何元素的子字符串

一种方法如下:

test = []
for elb in b:
    included = False
    for ela in a:
        if elb in ela:
            included = True
        break
    test.append(included)

我觉得这不是一个很好的方法,也许有一个理解可以改进它

以下方法也有效:

[True if any(elb in ela for ela in a) else False for elb in b]

我只是在想可能会有更好的方法


Tags: 数据方法intestfalsetrue元素for
3条回答

这是我想到的另一种方法:

[x in "-".join(y for y in a) for x in b]

a的所有字符串连接到一个字符串中,并测试元素是否在其中

产出:

[True, False]

免责声明:不确定这是否确实“更好”,但好吧,同样,这只是另一种方法

这就足够了:

[ any(elb in ela for ela in a) for elb in b ]

首先,这个

True if True else False

这是多余的。所以在你的第一次比赛中。您可以有:[x in a for x in b],类似地,[any(elb in ela for ela in a) for elb in b]

我认为,就人物而言,这是一个简短的故事,你会得到它

但是,从效率角度来看,您可以从a中的所有字符串预生成所有可能的子字符串,并将它们存储在set

这将意味着复杂性将从O(n*m*p)(其中nb的长度,ma的长度,na的平均子字符串长度)减少到O(n)。这是因为,一旦创建了子字符串查找集,检查b中的特定元素就是一个O(1)操作,因为您要检查是否包含在一个集合中,而不是检查O(m*p)中的每个元素的每个子字符串

要生成此子字符串查找集,可以使用集合理解:

a_substrings = {s[i:j] for s in a for i in range(len(s)) for j in range(i+1, len(s)+1)}

然后,您只需检查in以下内容:

[s in a_substrings for s in b]

这将为您的输入提供预期的[True, False]


这真的更快吗?

对于小规模的ab列表,创建查找集的开销将超过能够检查b中每个元素的优势。此外,对于一个非常长的a列表,它包含长的strings,甚至是一个中等大小的b,遍历a的所有子字符串并创建查找集可能会更慢,特别是当b中的大多数元素将在a的前几个字符串中匹配时

但是,在两个列表都很长的情况下,最重要的是当b很长时,您的方法将不断地为b的每个元素一次又一次地生成和检查a的相同元素。显然,这比预先计算子集要慢。我想这本质上是搜索引擎的一个关键优化——当有人提出一个查询时,他们不会每次都从一张白板上拖网搜索网站,相反,他们会不断地重新评估所有已知的网站,当然是按照受欢迎程度的顺序,以便在收到查询时“随时准备”

相关问题 更多 >