У меня есть список списков, где списки всегда упорядочены одинаково, и в каждом списке несколько элементов дублируются. Поэтому я хотел бы удалить дубликаты из списка, но важно сохранить структуру каждого списка. то есть, если элементы с индексами 0, 1 и 2 являются дубликатами для данного списка, два из них будут удалены из списка, но тогда элементы с одинаковыми позициями также должны быть удалены из всех других списков, чтобы сохранить упорядоченную структуру .
Однако важно отметить, что элементы с индексами 0, 1 и 2 могут не дублироваться в других списках, и поэтому я хотел бы сделать это только в том случае, если бы я был уверен, что в списках элементы с индексами 0, 1 и 2 всегда дублировались.
В качестве примера, скажем, у меня был этот список списков
L = [ [1,1,1,3,3,2,4,6,6],
[5,5,5,4,5,6,5,7,7],
[9,9,9,2,2,7,8,10,10] ]
После применения моего метода я хотел бы остаться с
L_new = [ [1,3,3,2,4,6],
[5,4,5,6,5,7],
[9,2,2,7,8,10] ]
где вы видите, что элементы с индексами 1 и 2 и элемент 8 постоянно удаляются, потому что они последовательно дублируются во всех списках, тогда как элементы с индексами 3 и 4 не удаляются, потому что они не всегда дублируются.
Мои мысли до сих пор (хотя я считаю, что это, вероятно, не лучший подход, и поэтому я обратился за помощью)
def check_duplicates_in_same_position(arr_list):
check_list = []
for arr in arr_list:
duplicate_positions_list = []
positions = {}
for i in range(len(arr)):
item = arr[i]
if item in positions:
positions[item].append(i)
else:
positions[item] = [i]
duplicate_positions = {k: v for k, v in positions.items() if len(v) > 1}
for _, item in duplicate_positions.items():
duplicate_positions_list.append(item)
check_list.append(duplicate_positions_list)
return check_list
Это возвращает список списков списков, где каждый элемент представляет собой список, содержащий группу списков, элементы которых являются индексами дубликатов для этого списка, как так
[[[0, 1, 2], [3, 4], [7, 8]],
[[0, 1, 2, 4, 6], [7, 8]],
[[0, 1, 2], [3, 4], [7, 8]]]
Я тогда подумал как-то сравнить эти списки и например удалить элементы с индексом 1 и 2 и с индексом 8, потому что это общие совпадения для каждого.
Вы разбили эту задачу на более мелкие части? С какой частью этой задачи вы боретесь? Вы можете найти, какие элементы являются дубликатами в одном списке? Вы можете сопоставить их во всех списках? Где ты застрял?
«элементы 1 и 2 и элемент 8 постоянно удаляются». Элемент 8 появляется одинаковое количество раз в L
и L_new
. Вы имеете в виду 8-й элемент, то есть элемент с индексом 7? Важно ли удалить первые экземпляры дубликатов (т. е. первый и второй, а не второй и третий элемент) или элементы неразличимы?
разве вывод не должен быть [[1, 3, 2, 6], [5, 4, 6, 7], [9, 2, 7, 10]]
?
@sahasrara62 добавил мою попытку.
@MisterMiyagi да, извините, я имею в виду элемент, проиндексированный номерами 1, 2 и 8, отредактировал публикацию, чтобы сделать ее более понятной. И да, они неразличимы, если они являются дубликатами, поэтому можно удалить любой из них, чтобы просто оставить один оставшийся.
@Pronitron, значит, вы хотите удалить первый повторяющийся элемент, и все элементы соответствуют индексу дубликата в подсписке?
@ sahasrara62 нет, вывод не должен быть таким, как я сказал, одни и те же элементы индекса должны быть последовательно удалены из всех подсписков, чтобы оставить только один из нескольких дубликатов, но это следует делать только в том случае, если одни и те же элементы индекса во всех подсписках дублируются в своих соответствующий подсписок.
каков будет ожидаемый результат, когда исходный список: [[1,1,1],[1,1,1],[1,2,1]]
? уже увиденная тройка но не в повторе считается увиденной или новой?
@GáborFekete, в этом случае мы бы сказали, что элементы с индексами 0 и 2 последовательно дублируются в подсписках, поэтому можно удалить либо индекс элемента 0, либо индекс 2, чтобы оставить [[1,1],[1,1],[1,2]] or [[1,1],[1,1],[2,1]]
Я бы пошел с чем-то вроде этого. Это не слишком быстро, но в зависимости от размера ваших списков этого может быть достаточно.
L = [ [1,1,1,3,3,2,4,6,6], [5,5,5,4,5,6,5,7,7], [9,9,9,2,2,7,8,10,10] ]
azip = zip(*L)
temp_L = []
for zz in azip:
if not zz in temp_L:
temp_L.append(zz)
new_L = [list(zip(*temp_L))[zz] for zz in range(len(L))]
сначала мы заархивируем три (или более) списка в L. Затем мы перебираем каждый элемент, проверяя, существует ли он уже. Если нет, мы добавляем его в наш временный список temp_L. И в конце мы реструктурируем temp_L, чтобы он имел исходный формат. Он возвращается
new_L
>> [(1, 3, 3, 2, 4, 6), (5, 4, 5, 6, 5, 7), (9, 2, 2, 7, 8, 10)]
«не слишком быстро» — это преуменьшение — это откровенно расточительно, находясь в диапазоне от O (n ^ 2) до O (n ^ 3) без какой-либо пользы. Использование списка для temp_L
делает if not zz in temp_L
тест чрезвычайно медленным, а создание new_L
постоянно создает правильное решение только для того, чтобы отбросить его и построить правильное решение из нескольких сохраненных частей.
Как написано, в зависимости от размера списков этого может быть достаточно. Мы не знаем, в каком контексте существует их проблема. Если в любом случае это не узкое место, то читаемость может стоить «медлительности».
Предполагая, что все подсписки будут иметь одинаковую длину, это должно работать:
l = [ [1,1,1,3,3,2,4,6,6], [5,5,5,4,5,6,5,7,7], [9,9,9,2,2,7,8,10,10] ]
[list(x) for x in zip(*dict.fromkeys(zip(*l)))]
# Output: [[1, 3, 3, 2, 4, 6], [5, 4, 5, 6, 5, 7], [9, 2, 2, 7, 8, 10]]
zip(*l)
— это создаст новый одномерный массив. N-й элемент будет кортежем со всеми n-ми элементами в исходных подсписках:[(1, 5, 9),
(1, 5, 9),
(1, 5, 9),
(3, 4, 2),
(3, 5, 2),
(2, 6, 7),
(4, 5, 8),
(6, 7, 10),
(6, 7, 10)]
dict.fromkeys(<list>)
. Поскольку ключи Python dict должны быть уникальными, это удаляет дубликаты и генерирует следующий вывод:{(1, 5, 9): None,
(3, 4, 2): None,
(3, 5, 2): None,
(2, 6, 7): None,
(4, 5, 8): None,
(6, 7, 10): None}
zip
:zip(*dict.fromkeys(zip(*l)))
[list(x) for x in zip(*dict.fromkeys(zip(*l)))]
Пожалуйста, не просто выкладывайте решение, а объясните, как оно работает. Особенно использование dict.fromkeys
неочевидно, если только вы не знаете, как это работает.
Конечно! Я работаю над этим :)
Примечание. Принятый ответ по предоставленной ссылке также действителен! Должна быть создана функция для удаления дубликатов
так что вы пробовали до сих пор? поделитесь своим кодом и каким должен быть конечный результат