Since you specifically asked about efficiency:
# drewk's answer, optimized by using from_iterable instead of *
def double_chain(s):
return ''.join(chain.from_iterable(zip(s, s)))
# Ashwini Chaudhary's answer
def double_mult(s):
return ''.join([x*2 for x in s])
# Jon Clements' answer, but optimized to take the re.compile and *2 out of the loop.
r = re.compile('(.)')
def double_re(s):
return r.sub(r'\1\1', s)
Now:
In [499]: %timeit double_chain('abcd')
1000000 loops, best of 3: 1.99 us per loop
In [500]: %timeit double_mult('abcd')
1000000 loops, best of 3: 1.25 us per loop
In [501]: %timeit double_re('abcd')
10000 loops, best of 3: 22.2 us per loop
So, the itertools
method is about 60% slower than the simplest method, and using regexes is more than an order of magnitude slower still.
But a tiny string like this may not be representative for longer strings, so:
In [504]: %timeit double_chain('abcd' * 10000)
100 loops, best of 3: 4.92 ms per loop
In [505]: %timeit double_mult('abcd' * 10000)
100 loops, best of 3: 5.57 ms per loop
In [506]: %timeit double_re('abcd' * 10000)
10 loops, best of 3: 91.5 ms per loop
As expected, the itertools
method gets better (and now beats the simple way), and the regexp gets even worse as the string gets longer.
So, there is no one "most efficient" way. If you're doubling billions of tiny strings, Ashwini's answer is the best. If you're doubling millions of big strings, or thousands of huge strings, drewk's is best. And if you're doing neither… there's no reason to be optimizing this in the first place.
Also, usual caveats: This test is 64-bit CPython 3.3.0 on my Mac with no load; no guarantees the same will be true for your Python implementation, version, and platform, in your app, with your real data. A quick test with 32-bit 2.6 showed similar results, but if it matters, you need to run a more realistic and relevant test yourself.