嵌套列表中的列表理解

list comprehensions in a nested list

我有两个列表

onnet_data = [['one', 'test'], ['two', 'test2'], ['three', 'test3'], ['four', 'test4'], ['five', 'test5']]
elastic_data = [['one', 'test'], ['three', 'test3'], ['six', 'test6'], ['seven', 'test7']]

我正在尝试比较 onnet_data 和 elastic_data 的子列表中的第一个元素。如果匹配,我想从 onnet_data 中取出数据,如 common_data,然后在 onnet_data 中找到剩余的列表项。

onnet = [onnet_data[i][0] for i in range(len(onnet_data))]
elastic = [elastic_data[i][0] for i in range(len(elastic_data))]

common = list(set(onnet)& set(elastic))
common_data = []
for i in range(len(common)):
    for j in range(len(onnet_data)):
        if common[i] == onnet_data[j][0]:
            common_data.append(onnet_data[j])

我试过了

from operator import ne
from functools import partial
onnet_remaining = list(filter(partial(ne, common_data), onnet_data))

onnet_remaining 的预期输出是

[['two', 'test2'],  ['four', 'test4'], ['five', 'test5']]

但它打印了 onnet_data 的所有内容。我无法使用 list(set(onnet_data) - set(common_data)) 因为它是嵌套列表。

有什么办法吗?有没有其他简单的方法作为我的数据 与 len(onnet_data)=69973 和 len(elastic_data)=107730

更新:根据 roadrunner 的回答,列表有点不同。

onnet_data = [['one', 'test'], ['two', 'test2'], ['three', 'test3'], ['four', 'test4'], ['five', 'test5']]
elastic_data = [['one', 'something'], ['three', 'some3'], ['six', 'some6'], ['seven', 'some7']]

您可以在此处使用简单的列表理解:

>>> [x for x in onnet_data if x not in elastic_data]
[['two', 'test2'], ['four', 'test4'], ['five', 'test5']]

但是,列表查找是 O(N) 使用 in 并且对于较长的列表可能会很昂贵。您可以将 elastic_data 转换为一组元组(列表不可散列)以获得 O(1) 查找:

>>> lookup = set(map(tuple, elastic_data))
>>> [x for x in onnet_data if tuple(x) not in lookup]
[['two', 'test2'], ['four', 'test4'], ['five', 'test5']]

根据问题更新,如果要比较每个子列表中的第一个元素,可以使用 any():

>>> [[x, y] for x, y in onnet_data if not any(z == x for z, _ in elastic_data)]
[['two', 'test2'], ['four', 'test4'], ['five', 'test5']]

你也可以在这里使用集合来获得 O(1) 查找,因为使用 any()O(N):

>>> from operator import itemgetter
>>> lookup = set(map(itemgetter(0), elastic_data))
>>> [[x, y] for x, y in onnet_data if x not in lookup]
[['two', 'test2'], ['four', 'test4'], ['five', 'test5']]

这有效

onnet_data = [['one', 'test'], ['two', 'test2'], ['three', 'test3'], ['four', 'test4'], ['five', 'test5']]
elastic_data = [['one', 'test'], ['three', 'test3'], ['six', 'test6'], ['seven', 'test7']]

filtered_list = [string for string in onnet_data if string not in elastic_data]  
print("filtered list:", filtered_list)

输出:

filtered list: [['two', 'test2'], ['four', 'test4'], ['five', 'test5']]

你可以做一个列表理解:

from operator import itemgetter

onnet_data = [['one', 'test'], ['two', 'test2'], ['three', 'test3'], ['four', 'test4'], ['five', 'test5']]
elastic_data = [['one', 'test'], ['three', 'test3'], ['six', 'test6'], ['seven', 'test7']]

onnet_remaining = [datum for datum in onnet_data if datum[0] not in map(itemgetter(0), elastic_data)]