查找列表的索引,该列表是列表列表中的子集

时间:2015-11-20 22:05:48

标签: python list subset

我有两个非常大的列表(500万的订单)。

例如:

1)第一个列表a总是包含8个元素的列表。

2)第二个列表b总是包含4个元素的列表。

对于b中的每个列表,可能有多个子集,但这不是问题。

a=[[0 1 10 9 369 370 379 378],[1 2 11 10 370 371 380 379]..[[0 1 10 9 365 370 379 400]]

b=[[0 1 370 369],[1 2 371 370], ......]

我想知道b中每个列表中包含其所有元素的列表索引。

例如:我知道“b [0] = [0 1 370 369]”是“a [0] = [0 1 10 9 369 370 379 378]”的子集,因为b [中的所有元素] 0]包含在[0]中。 b [1]作为[1]的子集也是如此。

所以我想要一个这样的输出:c = [[0],[1] .......]。

如果有多个子集,我应该得到类似的东西:c = [[0],[1] .... [20,19] .....]

我的问题是我的代码太慢了:

index=[]
for i in range(len(b)):
    for j in range(len(a)):
        if set(b[i])<set(a[j]):
        print b[i]
        print a[j]
        print j
        index.append([j]) #index in a 

以下是我的代码输出:

[  0   1 370 369]
[  0   1  10   9 369 370 379 378]
0

[  1   2 371 370]
[  1   2  11  10 370 371 380 379]
1

.
.
[369 370 739 738]
[369 370 379 378 738 739 748 747]
320
.
.

在循环结束时len(index)= len(b),因为我确信b中的每个列表始终是a的子集。

每次迭代最多需要30/40秒。

我确信有更多的pythonic方式来执行相同的循环,我该如何加快它?

谢谢

1 个答案:

答案 0 :(得分:1)

构建一个字典,显示a中哪些列表包含每个数字:

import collections
number_locations = collections.defaultdict(set)
for i, l in enumerate(a):
    for num in l:
        number_locations[num].add(i)

然后对于b中的每个列表,查找a中可以找到其元素的位置,并使用集合交集来查找a中包含所有4个数字的元素:

index = [set.intersection(*[number_locations[num] for num in l]) for l in b]

这会产生一组集合;如果你真的需要列表,你可以在项目上调用list,或者sorted来获取排序的索引列表。