What is the simplest way to swap each pair of adjoining chars in a string with Python?

Posted on

Question :

What is the simplest way to swap each pair of adjoining chars in a string with Python?

I want to swap each pair of characters in a string. '2143' becomes '1234', 'badcfe' becomes 'abcdef'.

How can I do this in Python?

Asked By: cocobear

||

Answer #1:

oneliner:

>>> s = 'badcfe'
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
'abcdef'
  • s[x:x+2] returns string slice from x to x+2; it is safe for odd len(s).
  • [::-1] reverses the string in Python
  • range(0, len(s), 2) returns 0, 2, 4, 6 … while x < len(s)
Answered By: Paulo Scardine

Answer #2:

The usual way to swap two items in Python is:

a, b = b, a

So it would seem to me that you would just do the same with an extended slice. However, it is slightly complicated because strings aren’t mutable; so you have to convert to a list and then back to a string.
Therefore, I would do the following:

>>> s = 'badcfe'
>>> t = list(s)
>>> t[::2], t[1::2] = t[1::2], t[::2]
>>> ''.join(t)
'abcdef'
Answered By: Duncan

Answer #3:

Here’s one way…

>>> s = '2134'
>>> def swap(c, i, j):
...  c = list(c)
...  c[i], c[j] = c[j], c[i]
...  return ''.join(c)
...
>>> swap(s, 0, 1)
'1234'
>>>
Answered By: FogleBird

Answer #4:

Loop over length of string by twos and swap:

def oddswap(st):
    s = list(st)
    for c in range(0,len(s),2):
        t=s[c]
        s[c]=s[c+1]
        s[c+1]=t

    return "".join(s)

giving:

>>> s
'foobar'
>>> oddswap(s)
'ofbora'

and fails on odd-length strings with an IndexError exception.

Answered By: Spacedman

Answer #5:

''.join(s[i+1]+s[i] for i in range(0, len(s), 2)) # 10.6 usec per loop

or

''.join(x+y for x, y in zip(s[1::2], s[::2])) # 10.3 usec per loop

or if the string can have an odd length:

''.join(x+y for x, y in itertools.izip_longest(s[1::2], s[::2], fillvalue=''))

Note that this won’t work with old versions of Python (if I’m not mistaking older than 2.5).

The benchmark was run on python-2.7-8.fc14.1.x86_64 and a Core 2 Duo 6400 CPU with s='0123456789'*4.

Answered By: Cristian Ciupitu

Answer #6:

If performance or elegance is not an issue, and you just want clarity and have the job done then simply use this:

def swap(text, ch1, ch2):
    text = text.replace(ch2, '!',)
    text = text.replace(ch1, ch2)
    text = text.replace('!', ch1)
    return text

This allows you to swap or simply replace chars or substring.
For example, to swap ‘ab’ <-> ‘de’ in a text:

_str = "abcdefabcdefabcdef"
print swap(_str, 'ab','de') #decabfdecabfdecabf
Answered By: john doe

Answer #7:

There is no need to make a list. The following works for even-length strings:

r = ''
for in in range(0, len(s), 2) :
  r += s[i + 1] + s[i]
s = r
Answered By: cayhorstmann

Answer #8:

Do you want the digits sorted? Or are you swapping odd/even indexed digits? Your example is totally unclear.

Sort:

s = '2143'
p=list(s)
p.sort()
s = "".join(p)

s is now ‘1234’. The trick is here that list(string) breaks it into characters.

Answered By: Spacedman

Leave a Reply

Your email address will not be published. Required fields are marked *