Как найти общие позиции в списке списков, где элементы всегда дублируются, а затем удалить эти дубликаты?

У меня есть список списков, где списки всегда упорядочены одинаково, и в каждом списке несколько элементов дублируются. Поэтому я хотел бы удалить дубликаты из списка, но важно сохранить структуру каждого списка. то есть, если элементы с индексами 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, потому что это общие совпадения для каждого.

так что вы пробовали до сих пор? поделитесь своим кодом и каким должен быть конечный результат

sahasrara62 17.01.2023 15:59

Вы разбили эту задачу на более мелкие части? С какой частью этой задачи вы боретесь? Вы можете найти, какие элементы являются дубликатами в одном списке? Вы можете сопоставить их во всех списках? Где ты застрял?

Pranav Hosangadi 17.01.2023 16:07

«элементы 1 и 2 и элемент 8 постоянно удаляются». Элемент 8 появляется одинаковое количество раз в L и L_new. Вы имеете в виду 8-й элемент, то есть элемент с индексом 7? Важно ли удалить первые экземпляры дубликатов (т. е. первый и второй, а не второй и третий элемент) или элементы неразличимы?

MisterMiyagi 17.01.2023 16:11

разве вывод не должен быть [[1, 3, 2, 6], [5, 4, 6, 7], [9, 2, 7, 10]] ?

sahasrara62 17.01.2023 16:22

@sahasrara62 добавил мою попытку.

Pronitron 17.01.2023 16:24

@MisterMiyagi да, извините, я имею в виду элемент, проиндексированный номерами 1, 2 и 8, отредактировал публикацию, чтобы сделать ее более понятной. И да, они неразличимы, если они являются дубликатами, поэтому можно удалить любой из них, чтобы просто оставить один оставшийся.

Pronitron 17.01.2023 16:25

@Pronitron, значит, вы хотите удалить первый повторяющийся элемент, и все элементы соответствуют индексу дубликата в подсписке?

sahasrara62 17.01.2023 16:26

@ sahasrara62 нет, вывод не должен быть таким, как я сказал, одни и те же элементы индекса должны быть последовательно удалены из всех подсписков, чтобы оставить только один из нескольких дубликатов, но это следует делать только в том случае, если одни и те же элементы индекса во всех подсписках дублируются в своих соответствующий подсписок.

Pronitron 17.01.2023 16:33

каков будет ожидаемый результат, когда исходный список: [[1,1,1],[1,1,1],[1,2,1]]? уже увиденная тройка но не в повторе считается увиденной или новой?

Gábor Fekete 17.01.2023 16:41

@GáborFekete, в этом случае мы бы сказали, что элементы с индексами 0 и 2 последовательно дублируются в подсписках, поэтому можно удалить либо индекс элемента 0, либо индекс 2, чтобы оставить [[1,1],[1,1],[1,2]] or [[1,1],[1,1],[2,1]]

Pronitron 17.01.2023 16:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
10
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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] ]

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 постоянно создает правильное решение только для того, чтобы отбросить его и построить правильное решение из нескольких сохраненных частей.

MisterMiyagi 17.01.2023 16:21

Как написано, в зависимости от размера списков этого может быть достаточно. Мы не знаем, в каком контексте существует их проблема. Если в любом случае это не узкое место, то читаемость может стоить «медлительности».

Lukas S 17.01.2023 16:29
Ответ принят как подходящий

Предполагая, что все подсписки будут иметь одинаковую длину, это должно работать:

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

Объяснение:

  1. 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)]
  1. Из предыдущего списка мы хотим сохранить только те, которые не повторяются. Существуют различные способы достижения этого. Если вы ищете, как удалить дубликаты, поддерживая порядок, появится этот ответ. Он использует 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}
  1. Теперь мы хотим распаковать эти ключи в исходный двумерный массив. Для этого мы можем снова использовать zip:
zip(*dict.fromkeys(zip(*l)))
  1. Поскольку zip возвращает кортежи, мы должны, наконец, преобразовать кортежи в список, используя понимание списка:
[list(x) for x in zip(*dict.fromkeys(zip(*l)))]

Пожалуйста, не просто выкладывайте решение, а объясните, как оно работает. Особенно использование dict.fromkeys неочевидно, если только вы не знаете, как это работает.

MisterMiyagi 17.01.2023 16:22

Конечно! Я работаю над этим :)

Carles Mitjans 17.01.2023 16:22

Примечание. Принятый ответ по предоставленной ссылке также действителен! Должна быть создана функция для удаления дубликатов

Carles Mitjans 17.01.2023 16:32

Другие вопросы по теме