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?
bon mot:
>>> s = 'badcfe'
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ])
'abcdef'
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'
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'
>>>
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
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
''.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
.
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.
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'
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
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.
>>> 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
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"))
Une autre façon:
>>> s='123456'
>>> ''.join([''.join(el) for el in Zip(s[1::2], s[0::2])])
'214365'