过滤成对(元组)列表,其中元组不包含来自其他lis的任何值

2024-06-01 09:40:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个元组列表:

my_list = [(1,2),(2,3),(3,4),(4,5),(5,6),(7,8)]

以及要排除的值列表,其格式如下:

reference_list = [(2,20),(3,46),(4,918)] 

我要排除的值是该对中的第一个。(20、46、918的含义并不重要)

所以我想返回一个元组列表,其中不包含任何2,3,4值。你知道吗

预期结果:

[(5,6),(7,8)] 

(因为所有其他值都包含一个或多个值2、3或4)

我试过的:

[p for p in my_list if p[0] not in [v[0] for v in reference_list] and p[1] not in [v[0] for v in reference_list]]

我正在检查该对的第一个或第二个值是否不在引用列表的列表v[0]中。你知道吗

它确实有效,但我正在寻找一个更简洁/Python的方式,如果有的话。理想的可扩展性(不需要添加条件,比如p[2]不在列表中,p[3]不在列表和中)。你知道吗


Tags: andin列表forifmy格式方式
3条回答

出于性能考虑,对于较大的列表,应创建一个包含第二个列表的第一个元素的集合:

list_a = [(1,2),(2,3),(3,4),(4,5),(5,6),(7,8)]
list_b = [(2,20),(3,46),(4,918)]

set_b = {t[0] for t in list_b}

result = [t for t in list_a if not set_b.intersection(t)]

一般来说,intersection方法比any快一点:

%timeit [t for t in list_a if not set_b.intersection(t)]
2.7 µs ± 377 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit [t for t in list_a if not any(el in set_b for el in t)]
4.97 µs ± 479 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

平的比嵌套的好

blacklist = {p[0] for p in blacklist_of_tuples}
[p for p in my_list if p[0] not in blacklist and p[1] not in blacklist]

这并不能解决一般情况,但您可以使用一点^{}

[p for p in my_list if not any(el in blacklist for el in p)]

将列表理解与^{}一起使用:

[x for x in lst1 if not any(y[0] in x for y in lst2)]

代码

lst1 = [(1,2),(2,3),(3,4),(4,5),(5,6),(7,8)]
lst2 = [(2,20),(3,46),(4,918)] 

set_lst2 = set(lst2)
print([x for x in lst1 if not any(y[0] in x for y in set_lst2)])
# [(5, 6), (7, 8)]

相关问题 更多 >