繁体   English   中英

您如何在另一个列表中按顺序查找一个列表中的元素?

[英]How do you find the elements in one list, in that order, in another list?

我正在尝试将一个列表(list1)中的所有项目与另一个列表(list2)中的一些项目进行匹配。

list1 = ['r','g','g',]
list2 = ['r','g','r','g','g']

对于 list1 中的每个连续 object,我想找到该模式出现在 list2 中的所有索引:

从本质上讲,我希望结果是这样的:

“r 位于 list2 中的索引 0,2”“r,g 位于 list2 中的索引 1,3”(我只想找到模式中的最后一个索引)“r,g,g 位于 list2 中的索引 4 "

至于我尝试过的事情:嗯......很多。

最接近的一个是这样的:

print([x for x in list1 if x not in set(list2)])

这对我不起作用,因为它不寻找一组对象,它只测试 list1 中的一个 object是否在 list2 中。

我真的不需要答案是pythonic甚至那么快。 只要有效!

任何帮助是极大的赞赏! 谢谢!

这是一个相当有趣的问题。 Python 具有强大的列表索引方法,可让您有效地进行这些比较。 从编程/数学的角度来看,您要做的是将较长列表的列表与您选择的模式进行比较。 这可以通过以下方式实现:

# sample lists
pattern = [1,2,3]
mylist = [1,2,3,4,1,2,3,4,1,2,6,7,1,2,3]

# we want to check all elements of mylist
# we can stop len(pattern) elements before the end
for i in range(len(mylist)-len(pattern)):
    # we generate a sublist of mylist, and we compare with list pattern
    if mylist[i:i+len(pattern)]==pattern:
        # we print the matches
        print(i)

此代码将打印 0 和 4,即我们在 mylist 中有 [1,2,3] 的索引。

这是一个尝试:

list1 = ['r','g','g']
list2 = ['r','g','r','g','g']

def inits(lst):
    for i in range(1, len(lst) + 1):
        yield lst[:i]

def rolling_windows(lst, length):
    for i in range(len(lst) - length + 1):
        yield lst[i:i+length]

for sublen, sublst in enumerate(inits(list1), start=1):
    inds = [ind for ind, roll
            in enumerate(rolling_windows(list2, sublen), start=sublen)
            if roll == sublst]
    print(f"{sublst} is in list2 at indices: {inds}")

# ['r'] is in list2 at indices: [1, 3]
# ['r', 'g'] is in list2 at indices: [2, 4]
# ['r', 'g', 'g'] is in list2 at indices: [5]

基本上,它使用两个函数( initsrolling_windows )生成相关的子列表,然后比较它们。

纯 python 解决方案对于大型列表来说会很慢:

def ind_of_sub_list_in_list(sub: list, main: list) -> list[int]:
    indices: list[int] = []
    for index_main in range(len(main) - len(sub) + 1):
        for index_sub in range(len(sub)):
            if main[index_main + index_sub] != sub[index_sub]:
                break
        else:  # `sub` fits completely in `main`
            indices.append(index_main)

    return indices


list1 = ["r", "g", "g"]
list2 = ["r", "g", "g", "r", "g", "g"]
print(ind_of_sub_list_in_list(sub=list1, main=list2))  # [0, 3]

使用两个 for 循环逐项检查两个列表的简单实现。

将您需要匹配的列表转换为字符串,然后使用正则表达式并找到所有 substring

import re
S1 = "".join(list2) #it will convert your list2 to string
sub_str = ""
for letter in list1:
    sub_str+=letter
    r=re.finditer(sub_str, S1)
    for i in r:
        print(sub_str , " found at ", i.start() + 1)

这将为您提供匹配项目的起始索引

如果两个列表中的所有条目实际上都是字符串,则解决方案可以简化为:

list1 = ["r", "g", "g"]
list2 = ["r", "g", "g", "r", "g", "g"]
main = "".join(list2)
sub = "".join(list1)
indices = [index for index in range(len(main)) if main.startswith(sub, index)]
print(indices)  # [0, 3]

我们join两个列表连接到一个字符串,然后使用startswith方法来确定所有索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM