3

我有一个长字符串列表,我想获取与另一个列表中的字符串子字符串匹配的列表元素的索引。检查列表项是否在列表中包含单个字符串很容易使用列表推导来完成,例如这个问题

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
thing_to_find = "abc"
matching = [i for i, x in enumerate(my_list) if thing_to_find in x]

但是,我不仅要检查 if "abc"is in x,还要检查另一个列表中的任何字符串是否在列表中,如下所示:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
things_to_find = ['abc', 'def']

这显然是行不通的(但如果这样做会很酷):

matching = [i for i, x in enumerate(my_list) if things_to_find in x]

如果我单独运行命令,我可以找到列表索引,但这既乏味又可怕:

print([i for i, x in enumerate(my_list) if 'abc' in x])
# [0, 3]
print([i for i, x in enumerate(my_list) if 'def' in x])
# [1]

找到一个列表中的元素在另一个列表中找到的所有实例的索引的最佳方法是什么?

4

6 回答 6

5

您正在这里寻找any()功能:

matching = [i for i, x in enumerate(my_list) if any(thing in x for thing in things_to_find)]

演示:

>>> my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> things_to_find = ['abc', 'def']
>>> [i for i, x in enumerate(my_list) if any(thing in x for thing in things_to_find)]
[0, 1, 3]
于 2013-08-13T14:33:46.060 回答
1

构建一个正则表达式,然后针对它测试每个列表元素:

import re
#must use search, not match because no wildcards, unless only looking for prefixes
regex = re.compile('|'.join(re.escape(interest) for interest in things_to_find))

不要在每次搜索时重建正则表达式 - 仅在things_to_find更改时重建。

我怀疑你不想要索引,但元素:

[x for x in my_list if regex.search(x)]

或者,如果你真的想要索引:

[i for i,x in enumerate(my_list) if regex.search(x)]

对于大型列表,这可能会比any(in)解决方案(二次方)表现得更好things_to_find,但对于短列表来说将是过度的。你也会看到更多的收获,其中的东西things_to_find是相似的;如果您可以排序things_to_find以使更可能的匹配首先出现,并且如果匹配是可能的,那么收益就会减少。

于 2013-08-13T14:40:24.513 回答
1

也许是这样的?:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
things_to_find = ['abc', 'def']
for n, e in enumerate(my_list):
    for m in things_to_find:
        if m in e:
            print '%s is in %s at %s' % (m, e, n)

输出:

abc is in abc-123 at 0
def is in def-456 at 1
abc is in abc-456 at 3
于 2013-08-13T14:31:39.360 回答
1

你很接近:

matching = [i for i, x in enumerate(my_list) for keyword in things_to_find if keyword in x]

这给出了[0,1,3].

您还需要遍历things_to_find列表,看看是否keywordx.

于 2013-08-13T14:32:14.363 回答
1

可能有点慢,但为什么不试试:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
things_to_find = ['abc', 'def']
for thing_to_find in things_to_find:
    matching = [i for i, x in enumerate(my_list) if thing_to_find in x]
于 2013-08-13T14:33:42.073 回答
0
my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
things_to_find = ['abc', 'def']
matching = [[i for i, x in enumerate(my_list) if y in x]for y in things_to_find]
于 2013-08-13T14:39:57.807 回答