Как сохранить уникальные внутренние списки в списке списков, игнорируя один элемент внутреннего списка - PullRequest
0 голосов
/ 13 января 2020

У меня есть список списков, и я хотел бы сохранить уникальные списки, игнорируя один элемент списка.

MWE :

my_list_of_lists = [['b','c','1','d'],['b','c','1','d'],['b','c','2','e']]

print(my_list_of_lists)

new_list_of_lists = []

for the_list in my_list_of_lists:
    if the_list not in new_list_of_lists:
        new_list_of_lists.append(the_list)

print(new_list_of_lists)

MWE Вывод:

[['b', 'c', '1', 'd'], ['b', 'c', '1', 'd'], ['b', 'c', '2', 'e']]  # 1st print
[['b', 'c', '1', 'd'], ['b', 'c', '2', 'e']]                        # 2nd print

Вопрос:

Существует ли способ Pythoni c для удаления дубликатов, как в примере выше, игнорируя конкретный c элемент во внутреннем списке? ie для my_list_of_lists = [['b','c','1','d'],['b','c','3','d'],['b','c','2','e']] должно дать [['b','c','1','d'],['b','c','2','e']]

my_list_of_lists = [['b','c','1','d'],['b','c','3','d'],['b','c','2','e']] 
# my_list_of_lists[0] and my_list_of_lists[1] are identical 
# if my_list_of_lists[n][-2] is ignored

print(my_list_of_lists)

new_list_of_lists = []

for the_list in my_list_of_lists:
    if the_list[ignore:-2] not in new_list_of_lists: #ignore the second last element when comparing
        new_list_of_lists.append(the_list)

print(new_list_of_lists)

Ответы [ 3 ]

2 голосов
/ 13 января 2020

Это не "Pythoni c" как таковое, но оно относительно короткое и выполняет свою работу:

my_list_of_lists = [['b','c','1','d'],['b','c','3','d'],['b','c','2','e']] 

print(my_list_of_lists)

new_list_of_lists = []

ignore = 2

for the_list in my_list_of_lists:
    if all(
      any(e != other_list[i]
          for i, e in enumerate(the_list)
          if i != ignore)
      for other_list in new_list_of_lists
    ):
        new_list_of_lists.append(the_list)

print(new_list_of_lists)

Для данного ввода выводится [['b', 'c', '1', 'd'], ['b', 'c', '2', 'e']].

2 голосов
/ 13 января 2020

Мой вопрос и ваш ответ из комментариев:

"игнорирование указанного c элемента" - какой? Первый? Самый большой? Тот, который ди git? Какое-то другое правило? Ваш пример ввода не указывает. - Переполнение кучи

@ HeapOverflow, я думаю, что функция generi c (не указана c) будет наилучшей, так как другие пользователи в будущем могут интегрировать этот generi c функция для собственного использования. - 3kst c

Выполнение этого стиля @ GreenCloakGuy:

def unique(values, key):
    return list({key(value): value for value in values}.values())

new_list_of_lists = unique(my_list_of_lists, lambda a: tuple(a[:2] + a[3:]))

Немного короче:

def unique(values, key):
    return list(dict(zip(map(key, values), values)).values())

Те, кто принимает последний дубликат. Если вы хотите первое, вы можете использовать это:

def unique(values, key):
    tmp = {}
    for value in values:
        tmp.setdefault(key(value), value)
    return list(tmp.values())
1 голос
/ 13 января 2020

Следующий подход

  1. Создает dict
    1. , где значениями являются списки в списке списков
    2. , а соответствующие ключи - эти списки без индексов, которые вы хотите игнорировать, преобразуются в кортежи (поскольку списки не могут использоваться в качестве ключей dict, но кортежи могут)
  2. Получает значения dict, которые должны появляться в порядке вставки
  3. Преобразует это в список и возвращает его

Это сохраняет более поздние элементы в исходном списке, поскольку они перезаписывают более ранние элементы, которые являются «идентичными».

def filter_unique(list_of_lists, indices_to_ignore):
    return list({
        tuple(elem for idx, elem in enumerate(lst) if idx not in indices_to_ignore) : lst
        for lst in list_of_lists
    }.values())

mlol = [['b','c','1','d'],['b','c','3','d'],['b','c','2','d']] 
print(filter_unique(mlol, [2]))
# [['b', 'c', '3', 'd'], ['b', 'c', '2', 'e']]
print(filter_unique(mlol, [3]))
# [['b', 'c', '1', 'd'], ['b', 'c', '3', 'd'], ['b', 'c', '2', 'e']]

Это однострочник, злоупотребляющий диктовкой. Многострочная версия может выглядеть так:

def filter_unique(list_of_lists, indices_to_ignore):
    dct = {}
    for lst in list_of_lists:
        key = []
        for idx, elem in enumerate(lst):
            if idx not in indices_to_ignore:
                key.append(elem)
        dct[tuple(key)] = lst
    return list(dct.values())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...