繁体   English   中英

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

[英]Python: check if item exists in variable amount of lists

我正在使用一个小型搜索引擎,但失去了某些要点。 我有多个包含项目的列表,我想检查所有列表中都存在哪些项目。 列表的数量可能会有所不同,因为它们是根据搜索查询中的单词数创建的,具体操作如下:

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熟练者。

有什么建议么?

提前致谢!

尝试以相反的方式进行操作:首先通过执行以下操作来创建所有索引列表的列表

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”列表将包含所有列表共有的元素。

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

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']

只需使用所有集合并使用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])

似乎有些东西掩盖了内置类型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。

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

暂无
暂无

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

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