Я пытаюсь удалить все дубликаты и оригиналы из вложенного списка на основе определенного столбца.
пример
list = [['abc',3232,'demo text'],['def',9834,'another text'],['abc',0988,'another another text'],['poi',1234,'text']]
Ключевой столбец - первый (abc, def, abc), и на основе этого я хочу удалить любой элемент (плюс оригинал), который имеет то же значение с оригиналом.
Поэтому новый список должен содержать:
newlist = [['def',9834,'another text'],['poi',1234,'text']]
Я нашел много похожих тем, но не для вложенных списков... Любая помощь, пожалуйста?
Используйте collections.Counter
:
from collections import Counter
lst = [['abc',3232,'demo text'],['def',9834,'another text'],['abc',988,'another another text'],['poi',1234,'text']]
d = dict(Counter(x[0] for x in lst))
print([x for x in lst if d[x[0]] == 1])
# [['def', 9834, 'another text'],
# ['poi', 1234, 'text']]
Также обратите внимание, что вы не должны указывать свой список как list
поскольку он затеняет встроенный list
.
Вы можете создать список ключей
keys = [x[0] for x in list]
и выберите только те записи, для которых ключ происходит ровно один раз
newlist = [x for x in list if keys.count(x[0]) == 1]
list.count
n раз. Вы можете использовать collections.Counter
чтобы сделать это O (n). Или хранить ваши счета отдельно.
Counter
является более эффективным подходом, но я намеревался дать быстрое и грязное решение, которое хорошо работает в большинстве случаев.
Использование collections.defaultdict
для решения O (n):
L = [['abc',3232,'demo text'],
['def',9834,'another text'],
['abc',988,'another another text'],
['poi',1234,'text']]
from collections import defaultdict
d = defaultdict(list)
for key, num, txt in L:
d[key].append([num, txt])
res = [[k, *v[0]] for k, v in d.items() if len(v) == 1]
print(res)
[['def', 9834, 'another text'],
['poi', 1234, 'text']]
Counter
чем путь по defaultdict
. +1.
Использование понимания списка.
Демо - версия:
l = [['abc',3232,'demo text'],['def',9834,'another text'],['abc', 988,'another another text'],['poi',1234,'text']]
checkVal = [i[0] for i in l]
print( [i for i in l if not checkVal.count(i[0]) > 1 ] )
Выход:
[['def', 9834, 'another text'], ['poi', 1234, 'text']]
list.count
n раз. Вы можете использовать collections.Counter
чтобы сделать это O (n). Или хранить ваши счета отдельно.
if x[0] in d.keys()
необходим?