Поиск дубликатов и их удаление

1

иногда у меня есть строка, подобная этой

string = "Hett, Agva,"

и иногда у меня будут дубликаты.

string = "Hett, Agva, Delf, Agva, Hett,"

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

ОБНОВИТЬ.

Поэтому во второй строке мне нужно удалить Agva и Hett, потому что в строке есть 2x из них

  • 1
    ',' также дубликат? Как вы определяете дубликаты?
  • 0
    если есть 2x Agva, мне нужно удалить один
Показать ещё 4 комментария
Теги:
python-2.7

5 ответов

2
Лучший ответ

Итерации над частями (словами) и добавление каждой части в набор замеченных частей и список частей, если он еще не находится в этом наборе. В заключение. восстановите строку:

seen = set()
parts = []
for part in string.split(','):
    if part.strip() not in seen:
        seen.add(part.strip())
        parts.append(part)

no_dups = ','.join(parts)

(обратите внимание, что мне пришлось добавить некоторые вызовы в .strip() поскольку в начале некоторых слов, которые этот метод удаляет, есть пробелы)

который дает:

'Hett, Agva, Delf,'

Зачем использовать набор?

Чтобы запросить, является ли элемент in наборе, это O(1) средний случай - поскольку они хранятся хешем, который делает постоянным время поиска. С другой стороны, поиск в списке - это O(n) поскольку Python должен перебирать список до тех пор, пока элемент не будет найден. Это означает, что для этой задачи гораздо эффективнее использовать set поскольку для каждого нового слова вы можете мгновенно проверить, видели ли вы раньше, тогда как вам нужно будет перебирать list видимых элементов, иначе для большого списка требуется намного больше времени.


О, и просто проверить, есть ли дубликаты, спросите, совпадает ли длина списка расщепления с набором этого списка (который удаляет дубликаты, но теряет порядок).

Т.е.

def has_dups(string):
    parts = string.split(',')
    return len(parts) != len(set(parts))

которая работает так, как ожидалось:

>>> has_dups('Hett, Agva,')
False
>>> has_dups('Hett, Agva, Delf, Agva, Hett,')
True
  • 0
    но Хетт, также является дубликатом,
  • 0
    @ Chaban33 Мой плохой, нужно лишить ведущих мест ... Теперь это работает :)
Показать ещё 2 комментария
1

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

string = "Hett, Agva, Delf, Agva, Hett,"
words_list = string.split()

unique_words = []
[unique_words.append(w) for w in words_list if w not in unique_words]
new_string = ' '.join(unique_words)
print (new_String)

Выход:

'Hett, Agva, Delf,'
  • 0
    Как только вы составите список только слов без запятой, просто выполните set(list_name) . Например x = ['a', 'b', 'a'] и set(x) дают {'a', 'b'} . Это может быть в дальнейшем преобразовано в список
  • 0
    @ Базингаа Нет, потому что тогда вы потеряете заказ. Моя логика необходима.
Показать ещё 4 комментария
1

Вы можете использовать toolz.unique или, что то же самое, unique_everseen рецепт в документах itertools или эквивалентно явное решение @JoeIddon.

Здесь решение с использованием сторонних toolz:

x = "Hett, Agva, Delf, Agva, Hett,"

from toolz import unique

res = ', '.join(filter(None, unique(x.replace(' ', '').split(','))))

print(res)

'Hett, Agva, Delf'

Я удалил пробел и использовал filter для очистки трейлинга , который может не потребоваться.

1

если вы получите строку только в этом формате, вы можете сделать следующее:

import numpy as np

string_words=string.split(',')
uniq_words=np.unique(string_words)

string=""
for word in uniq_words:
    string+=word+", "
string=string[:-1]

что делает этот код, так это то, что он разбивает слова на список, находит уникальные элементы и затем объединяет их в строку, как раньше

0

Это выглядит немного уродливо,

', '.join(set(filter(None, [i.strip() for i in string.split(',')])))

но делает работу;)

Надеюсь, поможет!! Пожалуйста, не стесняйтесь спрашивать, не ясно ли что-то :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню