ans*_*onw 4 python performance list sublist
我有一个包含许多子列表的列表.例如:
full_list = [[1, 1, 3, 4], [3, 99, 5, 2],[2, 4, 4], [3, 4, 5, 2, 60]]
Run Code Online (Sandbox Code Playgroud)
我还有另一个列表,名为省略.例如:
omit = [99, 60, 98]
Run Code Online (Sandbox Code Playgroud)
如果该子列表中的任何元素在省略列表中,我想删除full_list 中的子列表.例如,我希望结果列表是:
reduced_list = [[1, 1, 3, 4], [2, 4, 4]]
Run Code Online (Sandbox Code Playgroud)
因为只有这些子列表没有省略列表中的元素.
我猜是有一些简单的方法可以通过列表理解来解决这个问题,但我无法让它工作.我尝试了很多东西:例如:
reduced_list = [sublist for sublist in full_list if item for sublist not in omit]
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激!
ps,以上是一个简化的问题.我的最终目标是从非常长的列表(例如,500,000个子列表)中删除子列表,如果这些子列表中的任何元素(字符串)在"省略"列表中包含超过2000个字符串.
使用set和all():
>>> omit = {99, 60, 98}
>>> full_list = [[1, 1, 3, 4], [3, 99, 5, 2],[2, 4, 4], [3, 4, 5, 2, 60]]
>>> [item for item in full_list if all(x not in omit for x in item)]
[[1, 1, 3, 4], [2, 4, 4]]
Run Code Online (Sandbox Code Playgroud)
这种方法与@ alecxe(或@ÓscarLópez)解决方案的主要区别在于它all短路并且不会在内存中创建任何集合或列表,而set-intersection返回包含与omitset 共有的所有项目的新集合并且检查它的长度以确定是否有任何项目是常见的.(设置交叉在内部以C速度发生,因此它比使用的普通python循环更快all)
>>> import random
Run Code Online (Sandbox Code Playgroud)
没有项目相交:
>>> omit = set(random.randrange(1, 10**18) for _ in xrange(100000))
>>> full_list = [[random.randrange(10**19, 10**100) for _ in xrange(100)] for _ in xrange(1000)]
>>> %timeit [item for item in full_list if not omit & set(item)]
10 loops, best of 3: 43.3 ms per loop
>>> %timeit [x for x in full_list if not omit.intersection(x)]
10 loops, best of 3: 28 ms per loop
>>> %timeit [item for item in full_list if all(x not in omit for x in item)]
10 loops, best of 3: 65.3 ms per loop
Run Code Online (Sandbox Code Playgroud)
所有项目相交:
>>> full_list = [range(10**3) for _ in xrange(1000)]
>>> omit = set(xrange(10**3))
>>> %timeit [item for item in full_list if not omit & set(item)]
1 loops, best of 3: 148 ms per loop
>>> %timeit [x for x in full_list if not omit.intersection(x)]
1 loops, best of 3: 108 ms per loop
>>> %timeit [item for item in full_list if all(x not in omit for x in item)]
100 loops, best of 3: 1.62 ms per loop
Run Code Online (Sandbox Code Playgroud)
有些项目相交:
>>> omit = set(xrange(1000, 10000))
>>> full_list = [range(2000) for _ in xrange(1000)]
>>> %timeit [item for item in full_list if not omit & set(item)]
1 loops, best of 3: 282 ms per loop
>>> %timeit [x for x in full_list if not omit.intersection(x)]
1 loops, best of 3: 159 ms per loop
>>> %timeit [item for item in full_list if all(x not in omit for x in item)]
1 loops, best of 3: 227 ms per loop
Run Code Online (Sandbox Code Playgroud)