前一段时间遇到一个问题,这让我想知道解决这个问题的最佳方法是什么。
想要一个方法,它接受一个输入字符串并返回一个 bool 值,无论给定字符串是否只有 1 个字符重复(可以重复多次)
ie: 'abca' -> True, 'abab' -> False, 'aaaa' -> True
我的解决方案似乎有点令人费解,我想知道更好的方法
#!/usr/bin/env python
import collections
def hasOnlyOneDuplicate(string):
# turn string into a dictionary with counter and obtain a list of all the values/occurences of each letter
values = list(collections.Counter(string).values())
# then we remove all the numbers that are a 1
result = filter(lambda a: a!=1, values)
return len(result) == 1
如果给定的字符串只有 1 个重复字符,那么剩余列表的长度应该是 1,对吗?否则有多个字符重复
感谢帮助
最佳答案
另一种使用 str.count()
和短路欺骗计数器的方法:
def hasOnlyOneDuplicate(s):
nDupes = 0
for ch in set(s):
if s.count(ch) > 1:
nDupes += 1
if nDupes > 1:
return False
return (nDupes == 1)
更新
这个解决方案是最快的,尤其是对于长字长:
from collections import Counter
import string
import random
def hasOnlyOneDuplicate_pault(s):
nDupes = 0
for ch in set(s):
if s.count(ch) > 1:
nDupes += 1
if nDupes > 1:
return False
return (nDupes == 1)
def hasOnlyOneDuplicate_dev(s):
x = list(s)
if len(set([a for a in x if x.count(a) > 1]))==1:
return True
else:
return False
def hasOnlyOneDuplicate_john(s):
return len([c for c,v in Counter(s).items() if v > 1]) == 1
N = 1000
test_words = [
''.join(random.choice(string.lowercase) for _ in range(random.randint(3,30)))
for _ in range(N)
]
%%timeit
len([hasOnlyOneDuplicate_pault(s) for s in test_words])
# 100 loops, best of 3: 2.57 ms per loop
%%timeit
len([hasOnlyOneDuplicate_dev(s) for s in test_words])
# 100 loops, best of 3: 7.6 ms per loop
%%timeit
len([hasOnlyOneDuplicate_john(s) for s in test_words])
# 100 loops, best of 3: 9.61 ms per loop
更新 2
所有发布的答案都比 OP 的解决方案更快:
%%timeit
len([hasOnlyOneDuplicate(s) for s in test_words])
# 100 loops, best of 3: 10.9 ms per loop
关于Python-判断给定字符串是否只有 1 个字符重复的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48546347/