按元组元素过滤元组列表

时间:2016-11-16 18:49:43

标签: python performance python-2.7

我正在使用Python(2.7.9),我试图通过这些元组的元素列表来过滤元组列表。特别是,我的对象具有以下形式:

tuples = [('a', ['a1', 'a2']), ('b',['b1', 'b2']), ('c',['c1', 'c2'])]
filter = ['a', 'c']

我是Python的新手,过滤我可以发现的元组的最简单方法是使用以下列表理解:

tuples_filtered = [(x,y) for (x,y) in tuples if x in filter]

生成的筛选列表如下所示:

tuples_filtered = [('a', ['a1', 'a2']), ('c',['c1', 'c2'])]

不幸的是,这个列表理解似乎非常低效。我怀疑这是因为我的元组列表比我的过滤器,字符串列表大得多。特别是,筛选器列表包含30,000个单词,元组列表包含大约134,000个2元组。

2元组的第一个元素在很大程度上是不同的,但是有一些重复的第一个元素的实例(实际上不确定有多少,但与列表的基数相比,并不是很多)。

我的问题:是否有更有效的方法可以通过这些元组的元素列表来过滤元组列表?

(道歉,如果这是偏离主题或愚蠢。)

相关问题(未提及效率):

Filter a list of lists of tuples

1 个答案:

答案 0 :(得分:9)

在你写的评论中:

  

过滤器列表包含30,000个单词,元组列表包含大约134,000个2元组。

针对列表的

in包含测试需要O(N)线性时间,当你执行134k次时,它是。每次必须迭代所有这些元素以找到匹配项。鉴于您正在过滤,并非所有这些第一个元素都将出现在30k列表中,因此您执行的最多30k * 134k == 40亿次比较。

改为使用

filter_set = set(filter)

设置包容测试是O(1)常数时间;现在你把你的问题减少到134k测试。

你可以避免支出的一小部分时间是元组分配;使用索引来提取您正在测试的一个元素:

tuples_filtered = [tup for tup in tuples if tup[0] in filter_set]