список пониманий во вложенном списке - PullRequest
0 голосов
/ 20 июня 2019

У меня есть два списка

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

Я пытаюсь сравнить первые элементы в подсписках onnet_data иastic_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.Я не могу использовать список (set (onnet_data) - set (common_data)), так как это вложенный список.

есть ли способ?Есть ли другой простой способ, поскольку мои данные с len (onnet_data) = 69973 и len (astic_data) = 107730

update: в зависимости от ответа от roadrunner, список немного другой.

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

Ответы [ 3 ]

3 голосов
/ 20 июня 2019

Вы можете использовать простое понимание списка здесь:

>>> [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']]
1 голос
/ 20 июня 2019

Вы можете сделать понимание списка:

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)]
0 голосов
/ 20 июня 2019

это работает

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']]
...