You don't need Count
or OrderedDict
for this task. Here is an optimized approach (for a string of length n
complexity is 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)
Here is a benchmark with other answer that shows this method is almost 4-5 time faster:
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
Also you can do this task even faster using a suffix tree specially if you want to perform it on a large amount of data. Here is an optimized implementation of this algorithm by myself in github. You can also use the documentations and useful links if you are not familiar with this data structure and the algorithm https://github.com/kasramvd/SuffixTree
As another linear-based answer using str.counter
within a generator expression you can use following approach suggested by @Stefan Pochmann:
next((c, s.count(c)) for c in s if s.count(c) > 1)