【问题标题】:Intersect a set with a list of sets in python将集合与python中的集合列表相交
【发布时间】:2018-11-15 19:59:16
【问题描述】:

我有一组s 和一组l 列表,如下所示。

s = {1,2,3,4}
l = [{1}, {1,2,3}, {3}]

输出应该是

out = [{1}, {1,2,3}, {3}]

我正在使用以下代码来完成它。但我希望有更快的方法?也许是某种广播?

out = [i.intersection(s) for i in l]

编辑

列表l 可以长达1000 个元素。

我的最终目标是创建一个矩阵,该矩阵的元素长度为l 元素的成对交集的元素长度。所以sl 的一个元素。

out_matrix = list()
for s in l:
    out_matrix.append([len(i.intersection(s)) for i in l])

【问题讨论】:

  • 过早的优化是邪恶的 有多大的ll 你担心性能? x in yy 是一个集合时是 O(1),所以你当前有一个 O(n) 操作。

标签: python python-3.x set


【解决方案1】:

阅读这个问题时,我的第一个想法是“当然,使用numpy”。然后我决定做一些测试:

import numpy as np
from timeit import Timer

s = {1, 2, 3, 4}
l = [{1}, {1, 2, 3}, {3}] * 1000  # 3000 elements
arr = np.array(l)


def list_comp():
    [i.intersection(s) for i in l]


def numpy_arr():
    arr & s

print(min(Timer(list_comp).repeat(500, 500)))
print(min(Timer(numpy_arr).repeat(500, 500)))

这个输出

# 0.05513364499999995
# 0.035647999999999236

所以numpy 确实快了一点。真的值得吗?没有把握。 3000 个元素列表的 ~0.02 秒差异是可以忽略的(特别是考虑到我的测试甚至没有考虑创建 arr 所花费的时间这一事实。

请记住,即使使用numpy,我们仍然处于 O(n) 的基础上。不同之处在于numpyfor 循环下推到C 级别,这本质上比Python 的for 循环要快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 2013-12-16
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多