Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中与索引相关的列表相交_Python_List - Fatal编程技术网

如何在python中与索引相关的列表相交

如何在python中与索引相关的列表相交,python,list,Python,List,我知道这个问题看起来像是重复的。但我很难解决这个问题,也找不到一个有帮助的解决方案 我正在用python实现一个遗传算法来解决旅行商问题 假设我们有这些名单(旅游) 如您所见,[5,4]在整个3个列表中重复出现 一个常规的交集将返回列表中的所有元素 我想要一些函数,比如intersect_list(a,b) 返回[5,4] 有python内置的方法可以找到这个吗?或者你有什么建议吗 注意:我知道我可以循环它来解决这个问题,但请记住,在我的例子中,我有大约400个列表。每个人的长度是401 换句话

我知道这个问题看起来像是重复的。但我很难解决这个问题,也找不到一个有帮助的解决方案

我正在用python实现一个遗传算法来解决旅行商问题

假设我们有这些名单(旅游)

如您所见,[5,4]在整个3个列表中重复出现 一个常规的交集将返回列表中的所有元素

我想要一些函数,比如intersect_list(a,b)

返回[5,4]

有python内置的方法可以找到这个吗?或者你有什么建议吗

注意:我知道我可以循环它来解决这个问题,但请记住,在我的例子中,我有大约400个列表。每个人的长度是401

换句话说:我希望看到这些列表之间的公共路径

如果有什么不清楚的地方,请告诉我
提前谢谢

一个想法是,您可以使用

",".join(list)
然后将问题转化为两个字符串中最长的匹配子字符串

关于此问题的解决方案和讨论,请访问:

  • 您可以使用list函数将它们压缩成元组,并返回所有元素相同的元组

    a = [1,0,2,5,4,3,1]
    b = [1,2,5,4,3,0,1]
    c = [1,3,5,4,2,0,1]
    zipped_tuples = zip(a, b, c)
    

    您可以尝试利用这一点来获得位置交点。

    400长度为400的列表不是太大的问题。首先将每个序列分解为其所有可能的子序列,(长度
    N
    的列表大约有
    0.5*N**2
    可能的子序列)。然后将它们全部相交,取最长的一个

    a = [1,0,2,5,4,3,1]
    b = [1,2,5,4,3,0,1]
    c = [1,3,5,4,2,0,1]
    
    def longest_match_finder(lists):
        matches = []
        for a in lists:
            lengths = set()
            for leng in xrange(1,len(a)+1):
                lengths = lengths | set(tuple(a[i:i+leng]) 
                                        for i in xrange(len(a)-leng+1))
            matches.append(lengths)
        return max(set.intersection(*matches), key=len)
    
    print longest_match_finder([a,b,c])
    #Output:
    (5, 4)
    
    使用
    400
    列出每个
    400
    元素,这大约需要
    280秒(在我非常旧的机器上)。但是,如果我们只对一个列表使用相同的方法,但使用
    str(list).strip(“[]”)
    将其子序列和所有其他列表转换为字符串(由@pyfunc首先发布),我们可以更快地搜索。相同的测试在
    21秒内运行

    import ast
    
    def longest_match_finder_2(lists):
        a = lists[0]
        lengths = set()
        for leng in xrange(1,len(a)+1):
            lengths = lengths | set(str(a[i:i+leng]).strip('[]') 
                                    for i in xrange(len(a)-leng+1))
        for seq in lengths.copy():
            if not all([seq in str(i).strip('[]') for i in lists[1:]]):
                lengths.remove(seq)
        return ast.literal_eval(max(lengths, key=len))
    

    我们可以使用
    ast.literal\u eval()
    在最后(安全地)获取一个列表。

    在查看了@pyfunc发布的链接后,我得出了以下结论:

    def shortest_of(lists):
        return min(lists, key=len)
    
    def contains_sublist(lst, sublst):
        n = len(sublst)
        return any((sublst == lst[i:i+n]) for i in xrange(len(lst)-n+1)) 
    
    def longest_common(lists):
        if not lists:
            return ()
        res = set()    
        base = shortest_of(lists)
        length = len(base)
    
        for i in xrange(length, 0, -1):
            for j in xrange(length - i + 1):
                candidate = ', ' + str(base[j:i+j]).strip('[]') + ','
                #candidate = base[j:i+j]  
    
                for alist in lists:
                    if not candidate in ', ' + str(alist).strip('[]') + ',':
                    #if not contains_sublist(alist, candidate):   
                        break
                else:
                    res.add(tuple([int(a) for a in candidate[2:-1].split(',')]))
                    #res.add(tuple(candidate))
    
            if res:
                return tuple(res)    
    
        return ()
    
    if __name__ == '__main__':
        a = [1,0,2,5,4,3,1]
        b = [1,2,5,4,3,0,1]
        c = [1,3,5,4,2,0,1]
    
        print longest_common([a,b,c])
        print longest_common([b,c])
    
    输出:

    ((5, 4),)
    ((0, 1), (5, 4))
    
    编辑:
    更新了使用字符串转换和匹配的解决方案,因为它碰巧快多了。以前的解决方案部分已注释掉。而且,它现在提供了所有的可能性

    因此,澄清一下,您想要两个或更多项目在两个列表中以相同的顺序运行?所有列表都是彼此的输入排列吗?为什么
    不应该与列表(a,b)
    相交\u list(a,b)
    return
    [2,5,4,3]
    ?我觉得这是一个最长的常见连续子序列问题。为什么要转换为字符串?最长子字符串的算法适用于相同的列表way@JBernardo:是的,我在考虑最大的子串,因此得到了答案。我会更正它。这不起作用,因为子序列的索引不一定相同。有一个问题,请尝试
    最长匹配查找器([a,b])
    ,输出是
    (5,4,3)
    ,而它应该是
    (2,5,4,3)
    @Amr-谢谢,修复了它。愚蠢地将最大值视为大小而不是长度!我更新了我的代码,我的代码也使用了字符串。但是有一个小问题,例如:
    [1,2,3]
    将是
    '1,2,3'
    ,它将匹配
    [11,2,3]
    '11,2,3'
    。我也爱上了:)@Amr-是的,我注意到,就在我意识到我太累了,应该上床睡觉的时候:)很好,从大到小检查,不做所有的前期工作(就像我做的那样),会让事情变得更快:)是的,但我认为如果最大的公共子列表包含很少的元素,我的会更慢。我不擅长基准测试,所以我没有尝试过。@Amr:很高兴看到你解决了这个问题并把答案发回来了
    ((5, 4),)
    ((0, 1), (5, 4))