Python:检查项目是否存在可变数量的列表
我正在研究一个小型搜索引擎,并且我迷失了某个特定点。我有多个包含项目的列表,我想检查所有列表中存在哪些项目。列出的量可以改变,因为它们是基于搜索查询的单词数创建的,以做到:Python:检查项目是否存在可变数量的列表
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。
有什么建议吗?
提前致谢!
只需使用所有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])
谢谢!我没有意识到交集采用了任意数量的参数,这使得我的代码非常冗余。 – 2014-11-06 11:45:53
是的,'* index_list [:2]'获取列表中的每个集合,不包括设置为'shortest_list'的最后一个集合。 – 2014-11-06 11:48:19
这有帮助,谢谢!另一个问题是:* index_list后面的数字(在这种情况下是2)是手动放入的?在你的代码中,即使列表数量增加,它仍然保留:2。因为它需要适应列表的数量,对吗? – Ilse 2014-11-06 13:07:28
尝试去了解它相反的方式:一是通过执行类似
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']
有点令人困惑,你似乎有一些东西影响内置型,恰好为这种类型的工作而建造。
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))
注:由于帕德里克在他的回答,set.intersection指示,set.intersection_update都接受的自变量的任意数量,因此没有必要使用地图或减少这种情况。
由于交集可以优化为较小集合的大小,但是列表交集需要扫描列表,所以所有列表已经是集合,这也是最好的。
看看['itertools.product'](https://docs.python.org/2/library/itertools.html#itertools.product),这对于unpicking嵌套循环很有用 – jonrsharpe 2014-11-06 11:26:19