Удалить последовательные дубликаты из вложенного списка в Python? - PullRequest
1 голос
/ 09 мая 2020

У меня есть вложенный список со следующей структурой:

mylist = [['A', 'Car', '15'], ['A', 'Car', '15'], ['A', 'Plane', '16'], ['A', 'Bike', '20'], ['A', 'Car', '16'], ['A', 'Boat', '16']]

Он очень длинный, около 10 миллионов элементов. И таких списков у меня много. Я хочу сделать следующее:

Если третьи элементы (номера строк) каждого последовательного элемента из mylist являются дубликатами, удалите элементы, содержащие этот дубликат.

Например:

['A', 'Car', '15'] и ['A', 'Car', '15'] - это последовательные элементы из mylist, и оба они содержат '15', поэтому они являются последовательными дубликатами, и один должен быть удален.

Аналогично, ['A', 'Car', '16'] и ['A', 'Boat', '16'] являются последовательными, и оба содержат '16', поэтому один должен быть удален.

Итак, я бы получил следующее:

newlist = [['A', 'Car', '15'], ['A', 'Plane', '16'], ['A', 'Bike', '20'], ['A', 'Car', '16']]

Первоначально я написал следующее:

for ele in mylist:
    eleindex = mylist.index(ele)
    previousele = mylist[eleindex-1]
    if float(ele[2]) != float(previousele[2]):
        newlist.append(ele)

К сожалению, для таких длинных списков написанного мной кода потребовалось слишком много времени. Итак, я начал искать в Интернете и узнал, что библиотека itertools (с использованием groupby) полезна и очень быстро при выполнении подобных действий. Затем я нашел несколько примеров, которые я попытался эмулировать, однако они были в основном для простых списков, а не для чего-то более сложного, как моя ситуация. Поработав, я не смог понять, как использовать его для своих вложенных списков.

Итак, кто-нибудь знает, как это сделать очень быстро? Кроме того, если у вас есть решение, которое будет быстрее, чем itertools, это даже лучше!

1 Ответ

3 голосов
/ 09 мая 2020

Решение с itertools.groupby:

from itertools import groupby

mylist = [['A', 'Car', '15'], ['A', 'Car', '15'], ['A', 'Plane', '16'], ['A', 'Bike', '20'], ['A', 'Car', '16'], ['A', 'Boat', '16']]

out = [next(g) for _, g in groupby(mylist, lambda k: k[2])]

print(out)

Распечатывает:

[['A', 'Car', '15'], ['A', 'Plane', '16'], ['A', 'Bike', '20'], ['A', 'Car', '16']]

Контрольный показатель (со списком элементов 10_000_000):

from timeit import timeit
from random import randint
from itertools import groupby

mylist = []
for i in range(10_000_000):
    mylist.append(['X', 'X', str(randint(0, 20))])

def f1():
    out = [next(g) for _, g in groupby(mylist, lambda k: k[2])]
    return out

t1 = timeit(lambda: f1(), number=1)

print(t1)

Это печатается на моя машина (AMD 2400G, Python 3.8):

2.408908904006239
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...