Проверка того, имеет ли строка повторяющиеся символы

81
5

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


Например:


a = "12348546478"
#code to check multiple characters
print(result)

Результаты: 8 повторяли, 4 повторяли


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

спросил(а) 2015-08-19T11:17:00+03:00 5 лет, 2 месяца назад
1
Решение
70

Вы можете использовать collections.Counter:


>>> from collections import Counter
>>> [i for i,j in Counter(a).items() if j>1]
['4', '8']

Или вы можете использовать пользовательскую функцию:


>>> def finder(s):
... seen,yields=set(),set()
... for i in s:
... if i in seen:
... if i not in yields:
... yield i
... yields.add(i)
... else :
... yields.add(i)
... else:
... seen.add(i)
...
>>> list(finder(a))
['4', '8']

Или используйте метод str.count в понимании набора:


>>> set(i for i in a if a.count(i)>1)
set(['8', '4'])

Тест на все подходы, который показывает, что последний способ (пользовательская функция и множество понятий намного быстрее, чем Counter):

from timeit import timeit

s1="""
a = "12348546478"
[i for i,j in Counter(a).items() if j>1]

"""
s2="""
def finder(s):
seen,yields=set(),set()
for i in s:
if i in seen:
if i not in yields:
yield i
yields.add(i)
else :
yields.add(i)
else:
seen.add(i)

a = "12348546478"
list(finder(a))

"""

s3="""
a = "12348546478"
set(i for i in a if a.count(i)>1)
"""

print '1st: ' ,timeit(stmt=s1, number=100000,setup="from collections import Counter")
print '2nd : ',timeit(stmt=s2, number=100000)
print '3rd : ',timeit(stmt=s2, number=100000)


результат:


1st:  0.726881027222
2nd : 0.265578985214
3rd : 0.26243185997

Я также пробовал это для длинной строки (a = "12348546478"*10000) и получил тот же результат:


1st:  25.5780302721341
2nd : 11.8482989001177
3rd : 11.926538944245

В любом случае мое предложение использует множество понятий, более питоновское:


set(i for i in a if a.count(i)>1)

ответил(а) 2015-08-19T11:19:00+03:00 5 лет, 2 месяца назад
99

Или, альтернативно, вы могли бы сделать


len(set(x)) == len(x)

Это возвращает логическое значение True, если строка не имеет повторяющихся символов, False в противном случае.


Тип set не может иметь никаких дубликатов, поэтому, когда строка становится одной, она разбивается на символы. Разница в длине показывает, сколько повторяющихся символов было (но не сами символы)

ответил(а) 2015-08-19T11:27:00+03:00 5 лет, 2 месяца назад
70

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


import collections

d = collections.defaultdict(int)
for c in a:
d[c] += 1


d будет содержать {'1': 1, '3': 1, '2': 1, '5': 1, '4': 3, '7': 1, '6': 1, ' 8 ': 2}


И ответ, который дает Кашрамвд, - хороший подход.

ответил(а) 2015-08-19T11:38:00+03:00 5 лет, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема