我有一个长字符串列表,我想得到列表元素的索引与另一个列表中字符串的子字符串匹配。检查列表项是否在列表中包含单个字符串很容易使用列表推导,例如this question:
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]
但是,我不仅要检查"abc"
是否在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]
在另一个列表中找到一个列表中的元素的所有实例的索引的最佳方法是什么?
答案 0 :(得分: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]
答案 1 :(得分: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
答案 2 :(得分: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
列表,看看keyword
是否在x
。
答案 3 :(得分: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]
答案 4 :(得分: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
进行排序,以便首先发生更可能的匹配,并且可能匹配,则可以获得更少的收益。
答案 5 :(得分: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]