web-dev-qa-db-fra.com

Quel est le moyen le plus simple d'échanger un caractère dans une chaîne avec Python?

Je veux échanger chaque paire de caractères dans une chaîne. '2143' devient '1234', 'badcfe' devient 'abcdef'.

Comment puis-je faire cela en Python?

13
cocobear

bon mot:

>>> s = 'badcfe'
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
'abcdef'
  • s [x: x + 2] renvoie une tranche de chaîne de x à x + 2; c'est sûr pour len (s) impair (s).
  • [:: - 1] inverse la chaîne en Python
  • plage (0, len (s), 2) renvoie 0, 2, 4, 6 ... pendant que x <len (s)
13
Paulo Scardine

Le moyen habituel d’échanger des éléments en Python est le suivant:

a, b = b, a

Il me semble donc que vous faites simplement la même chose avec une tranche étendue. C'est un peu compliqué parce que les chaînes ne sont pas mutables, vous devez donc convertir en liste, puis revenir en chaîne, mais ce que je ferais, c'est:

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

Voici un moyen ...

>>> 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'
>>>
4
FogleBird

Il n'est pas nécessaire de faire une liste. Ce qui suit fonctionne pour les chaînes de longueur paire:

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

Si la performance ou l'élégance ne vous pose pas de problème et que vous souhaitez simplement la clarté et que le travail soit effectué, utilisez simplement ceci:

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

Cela vous permet d’échanger ou simplement de remplacer des caractères ou des sous-chaînes. Par exemple, d’échanger 'ab' <-> 'de' dans un texte:

_str = "abcdefabcdefabcdef"
print swap(_str, 'ab','de') #decabfdecabfdecabf
2
john doe
''.join(s[i+1]+s[i] for i in range(0, len(s), 2)) # 10.6 usec per loop

ou

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

ou si la chaîne peut avoir une longueur impaire:

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

Notez que cela ne fonctionnera pas avec les anciennes versions de Python (si je ne me trompe pas, c'est plus vieux que 2.5).

Le benchmark a été exécuté sur python-2.7-8.fc14.1.x86_64 et sur un processeur Core 2 Duo 6400 avec s='0123456789'*4.

2
Cristian Ciupitu

Boucle sur la longueur de la chaîne par deux et 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)

donnant:

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

et échoue sur les chaînes de longueur impaire avec une exception IndexError.

1
Spacedman

Ainsi:

>>> s = "2143658709"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'1234567890'

>>> s = "badcfe"
>>> ''.join([s[i+1] + s[i] for i in range(0, len(s), 2)])
'abcdef'
0
Lennart Regebro
def revstr(a):
    b=''
    if len(a)%2==0:
        for i in range(0,len(a),2):
            b += a[i + 1] + a[i]
        a=b
    else:
        c=a[-1]
        for i in range(0,len(a)-1,2):
            b += a[i + 1] + a[i]
        b=b+a[-1]
        a=b
    return b
a=raw_input('enter a string')
n=revstr(a)
print n
0
kevin

Voulez-vous que les chiffres soient triés? Ou échangez-vous des chiffres impairs/pairs indexés? Votre exemple est totalement incertain. 

Trier:

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

s est maintenant '1234'. Le truc est que la liste (chaîne) la divise en caractères.

0
Spacedman
>>> import ctypes
>>> s = 'abcdef'
>>> mutable = ctypes.create_string_buffer(s)
>>> for i in range(0,len(s),2):
>>>     mutable[i], mutable[i+1] = mutable[i+1], mutable[i]
>>> s = mutable.value
>>> print s
badcfe
0
JohnMudd
re.sub(r'(.)(.)',r"\2\1",'abcdef1234')

Cependant, c'est un peu lent.

def swap(s):
    i=iter(s)
    while True:
        a,b=next(i),next(i)
        yield b
        yield a

''.join(swap("abcdef1234"))
0
Kabie

Une autre façon:

>>> s='123456'
>>> ''.join([''.join(el) for el in Zip(s[1::2], s[0::2])])
'214365'
0
dansalmo