Python:检查项目是否存在于可变数量的列表中

时间:2014-11-06 11:22:26

标签: python list loops recursion

我正在使用一个小型搜索引擎,但我失去了一点。我有多个包含项目的列表,我想检查所有列表中存在哪些项目。列表的数量可能会有所不同,因为它们是根据搜索查询中的字数创建的,完成时间为:

index_list = [[] for i in range((len(query)+1))] 

我想我开始找出最短的列表是什么,因为那是需要检查的最大项目数。例如,使用三字搜索查询:

index_list[1]=[set(1,2,3,4,5)]
index_list[2]=[set(3,4,5,6,7)]
index_list[3]=[set(4,5,6,7)]

shortest_list = index_list[3] 

(最短的列表是什么,用功能计算,现在不相关)。

现在我想检查最短列表中的项目index_list [3]是否也存在于其他列表中。在这种情况下,总共有3个列表,但是当输入更长的搜索查询时,列表的数量会增加。我想用循环做一些事情,比如:

result = []
for element in shortest_list:
    for subelement in element:
        for element2 in index_list[1]:
            if subelement in element2:
                for element3 in index_list[2]:
                    if subelement in element3:
                        result.append(subelement)

所以,结果应该是:

[4, 5]

因为这些项目存在于所有列表中。

但是,当有更多列表时,上面的循环不会起作用。如前所述,我事先并不知道列表的数量,因为它取决于搜索查询中的单词数量。所以基本上我的循环深度取决于我的列表数量。

在做研究时,我发现一些帖子暗示递归可能会起作用。不幸的是,我不熟悉Python。

有什么建议吗?

提前致谢!

4 个答案:

答案 0 :(得分:0)

尝试以相反的方式进行:首先通过执行类似

的操作列出所有索引列表
index_list_list = []
for ix_list in get_index_lists(): #Or whatever
    index_list_list.append(ix_list)

然后你可以遍历所有这些,删除'remaining_items'列表中的元素,如果它们不包含在其他元素中:

remaining_items = shortest_list
for index_list in index_list_list:
    curr_remaining_items = copy(remaining_items)
    for element in curr_remaining_items:
        if element not in index_list:
            remaining_items.remove(element)

您的最终'remaining_items'列表将包含所有列表共有的元素。

答案 1 :(得分:0)

我按你的方法编写代码。您可以尝试以下代码:

index_list=['1','2','3','4','5']
index_list1=['3','4','5','6','7']
index_list2=['4','5','6','7']

result = []
for element in index_list:
   for subelement in element:
       for element2 in index_list1:
           if subelement in element2:
               for element3 in index_list2:
                   if subelement in element3:
                       result.append(subelement)
print result

输出:

['4', '5']

答案 2 :(得分:0)

只需使用所有sets并使用set.intersection查找常用元素,{1,2,3,4,5}就是如何创建一组不是set(1,2,3,4,5)的整数:

index_list = [set() for i in range(4)]
index_list[0].update({1,2,3,4,5})
index_list[1].update({3,4,5,6,7})
index_list[2].update({4,5,6,7})

shortest_list = index_list[2]

print(shortest_list.intersection(*index_list[:2]))
set([4, 5])

答案 3 :(得分:0)

有些令人困惑的是,您似乎有内置类型set的内容,这恰好是为这类工作而构建的。

subset = set(shortest_list)
# Use map here to only lookup method once.
# We don't need the result, which will be a list of None.
map(subset.intersection_update, index_lists)

# Alternative: describe the reduction more directly
# Cost: rebuilds a new set for each list
subset = reduce(set.intersection, index_lists, set(shortest_list))

注意:正如Padraic在他的回答中指出的那样,set.intersection和set.intersection_update都采用任意数量的参数,因此在这种情况下不必使用map或reduce。

最好还是所有列表都已设置,因为交叉点可以优化到较小集合的大小,但列表交集需要扫描列表。