Удалить дубликаты из списка и удалить соответствующие элементы из второго списка в Python - PullRequest
0 голосов
/ 17 июня 2019

У меня есть два списка. Одна содержит строки, которые представляют имена, а другая содержит целые числа, которые представляют людей. Для каждого имени есть соответствующий номер, и я могу получить доступ к каждому имени, потому что они находятся в одном индексе. Тем не менее, есть много повторяющихся имен, и я хочу удалить все повторяющиеся имена. Я подумал об использовании набора для удаления дубликатов, а затем преобразовать его обратно в список, подобный этому:

names = (list(set(names)))

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

Пример.

До:

Index    Name        Number
0        Alexander   12345
1        Elena       45678
2        John        76542
3        Alexander   43256
4        John        45024
5        David       69438   

После того, как:

NewIndex Name        Number
0        Alexander   12345
1        Elena       45678
2        John        76542
3        David       69438   

Ответы [ 3 ]

2 голосов
/ 17 июня 2019

Одна вещь, которую вы можете сделать, это сжать Name и Number вместе, а затем сделать диктат.Поскольку dict хэширует только на основе значения ключа, значение остается по-прежнему связанным с именем, но в остальном остается без изменений:

name_dict = dict(zip(names, numbers))
new_names, new_numbers = zip(*list(name_dict.items()))

Теперь, new_names по-прежнемусоответствует new_numbers по индексу, но не должно быть повторяющихся элементов.


Одно предостережение при таком подходе состоит в том, что last вхождение данного имени - это то, чьеномер имеет приоритет (например, "Alexander" будет соответствовать 43256, а не 12345).Это можно исправить, выполнив dict(reversed(zip(names, numbers))), чтобы изменить порядок, в котором dict читает и назначает ключи.

1 голос
/ 17 июня 2019

Вы можете использовать dict.setdefault(), чтобы просто сохранить имя по умолчанию, найденное в словаре:

data = [
    ('Alexander', 12345),
    ('Elena', 45678),
    ('John', 45678),
    ('Alexander', 43256),
    ('John', 45024),
    ('David', 69438)
]

result = {}
for name, number in data:
    result.setdefault(name, number)

print(list(result.items()))
# [('Alexander', 12345), ('Elena', 45678), ('John', 45678), ('David', 69438)]
0 голосов
/ 17 июня 2019

для этого массива

arr = [ ['Alexander',   12345],
        ['Elena',       45678],
        ['John',        76542],
        ['Alexander',   43256],
        ['John',        45024],
        ['David',       69438] ]

Предполагая, что вы хотите сохранить первый встреченный номер,

names = [a[0] for a in arr]
names_unique = list(set(names))

newarr = [ [name, arr[names.index(name)][1] ] for name in names_unique ]

Это даст:

[['Elena',      45678],
 ['David',      69438],
 ['Alexander',  12345],
 ['John',       76542]]

Это не быстрое решение, но для массивов длиной менее миллиона это будет сделано за секунду. .index может быть довольно дорогим для огромных массивов, поэтому в этом случае вы можете использовать классический сингл для цикла или попытаться получить предварительно отсортированный массив.

...