【发布时间】:2023-03-22 06:02:01
【问题描述】:
我有两个列表(listA,listB),每个列表由许多元组列表组成。
例如
listA = [ [(0,1), (1,2) ... ] , [(5,6), (6,10)] , ... ] # can have 5000 lists, each with 100+ tuples
listB = [...] # about the same structure
我想遍历listA中的每个列表,如果它不在listB中,我将它附加到listB。
所以它是这样的:
for lst in listA:
if lst not in listB: # membership checking
listB.append(lst)
我有数十万个这样的任务要执行,当 listA 和 listB 变大时,它似乎真的很慢。成员资格检查似乎是这里的瓶颈。我尝试使用字符串 '0-1' 而不是整数元组,但它并没有变得更快。有谁知道如何优化代码?列表成员检查真的很慢吗?
非常感谢任何帮助。谢谢!
------------- 编辑:这就是我最终使用的 -------------
谢谢各位。将嵌套列表转换为元组并使用集合!但是在遍历 listA 时必须小心,每个嵌套列表也必须转换为元组(但仅用于成员资格检查!)。我仍然需要将嵌套列表作为列表附加到 listB。那就是:
# first convert listB to a set of tuples
listB_as_set = set([tuple(x) for x in listB]) # O(N)
for lst in listA:
# convert the nested list to tuple
lst_tuple = tuple(lst)
# membership checking
if lst_tuple in listB_as_set: # now O(1), originally O(N)
listB.append(lst) # still appending as a list to listB
假设两个列表的长度为 N,并且忽略将 lst 转换为 lst_tuple 并将 lst 附加到 listB 的时间,如果我没记错的话,我们得到了从 O(N2) 到 O(N) 的改进。
【问题讨论】:
-
列表成员为
O(n),如果您不关心排序,则考虑将嵌套列表转换为tuple并使用sets。集合是O(1)用于成员资格检查。 -
@AChampion listA/listB 中列表的顺序无关紧要,但是对于每个嵌套列表,它必须是 (0,1), (1,2), ... I看。所以我将尝试将嵌套列表转换为元组并查看结果。谢谢!
-
您只需要转换
listB。 -
这是真的!但在循环中,我仍然必须将嵌套列表转换为元组以进行成员资格检查。
标签: python list membership