Вывести дубликаты в порядке появления
Дана строка:
s = 'asdf qwer zxcv. zxcv fdsa rewq. qazw asdf sxed. qwer crfv asdf.'
нужно получить все слова повторяющиеся более одного раза, в порядке их появления:
'zxcv asdf qwer'
Первым делом я привожу все к одному регистру, удаляю все знаки пунктуации и делю строку по пробелам на список слов:
s1 = re.sub(r'[^\w\s]', '', s.lower()).split(' ')
После чего я получаю список дубликатов:
s2 = [(i, s1.count(i)) for i in set(s1)]
ans = [i[0] for i in s2 if i[1]>1]
Как мне отсортировать этот список в порядке появления, как еще я могу получить этот список? Еслия пробую через разницу списков , в ответе повторяются слова, а должны попадать только один раз:
s1 = re.sub(r'[^\w\s]', '', s.lower()).split(' ')
s2 = list(set(s1))
for i in s2:
if i in s1:
s1.remove(i)
Ответы (2 шт):
Для начала можно посчитать частоту вхождения слов:
Вариант 1 - воспользоваться collections.Counter:
from collections import Counter
freq = Counter(s1)
Вариант 2 - воспользоваться обычным словарем:
freq = {}
for word in s1:
if word in freq:
freq[word] += 1
else:
freq[word] = 1
Вариант 3 - воспользоваться collections.defaultdict:
from collections import defaultdict
freq = defaultdict(int)
for word in s1:
freq[word] += 1
Чтобы получить список дубликатов из freq:
res = [w for w,n in freq.items() if n > 1]
Во всех случаях результат должен получиться одинаковым:
In [352]: res
Out[352]: ['asdf', 'qwer', 'zxcv']
Можно сделать все за один проход по списку s1:
freq = {}
res = []
for word in s1:
if word in freq:
freq[word] += 1
if word not in res:
res.append(word)
else:
freq[word] = 1
Вариант с использованием регулярки. Не очень красиво, но с вашим примером работает:
from re import search
s = 'asdf qwer zxcv. zxcv fdsa rewq. qazw asdf sxed. qwer crfv asdf.'
res, i = [], 0
while (m := search(r'\b\w+\b', s[i:])):
if m[0] not in res and search(f'{m[0]}', s[:i]):
res.append(m[0])
i += m.end()
print(res) # ['zxcv', 'asdf', 'qwer']