您不需要Count
或不需要OrderedDict
此任务。这是一种优化的方法(对于长度n
复杂度为 O(n) 的字符串):
In [35]: def first_repeated(s):
seen = set()
for i, j in enumerate(s):
if j in seen: # membership check in set is O(1)
return j, s.count(j, i + 1) + 2
seen.add(j)
....:
In [36]: first_repeated(s)
Out[36]: ('u', 2)
这是一个带有其他答案的基准测试,表明这种方法几乎快 4-5 倍:
In [39]: def counter_based(s):
....: c = Counter(s)
....: return next(key for key in c if c[key] > 1)
....:
In [40]: %timeit counter_based(s)
100000 loops, best of 3: 5.09 us per loop
In [41]: %timeit first_repeated(s)
1000000 loops, best of 3: 1.71 us per loop
如果您想在大量数据上执行此任务,您还可以使用后缀树更快地完成此任务。这是我自己在github中对该算法的优化实现。如果您不熟悉此数据结构和算法,也可以使用文档和有用的链接https://github.com/kasramvd/SuffixTree
作为在生成器表达式中使用的另一个基于线性的答案str.counter
,您可以使用@Stefan Pochmann 建议的以下方法:
next((c, s.count(c)) for c in s if s.count(c) > 1)