2011-01-05 9 views
13

Quiero intercambiar cada par de caracteres en una cadena. '2143' se convierte en '1234', 'badcfe' se convierte en 'abcdef'.¿Cuál es la forma más sencilla de intercambiar char en una cadena con Python?

¿Cómo puedo hacer esto en Python?

+0

Srsly, otra vez no. – gruszczy

+2

Al menos la q es clara ahora. Aunque sería más claro si la cadena original fuera 'foobar' y el resultado 'ofbora' - todavía parece una clasificación, ¡pero ahora sabemos que no lo es! – Spacedman

+1

Abajo votaron para volver a publicar la misma pregunta. * suspiro * – clifgriffin

Respuesta

13

oneliner:

>>> s = 'badcfe' 
>>> ''.join([ s[x:x+2][::-1] for x in range(0, len(s), 2) ]) 
'abcdef' 
  • s [x: x + 2] devuelve rebanada cadena de x a x + 2; es seguro para len (ones) impares.
  • [:: - 1] invierte la cadena en Python
  • rango (0, len (s), 2) devuelve 0, 2, 4, 6 ...mientras que X < len (s)
1

Ésta es una forma ...

>>> 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' 
>>> 
+0

¡hay una 's' en sus args y no 's' en su cuerpo! arreglado en una edición. – Spacedman

+1

s = '2143' no '2134' usaste indefinido var c – cocobear

+1

Eso solo intercambia el primer caracter, y si luego quieres intercambiar todo lo que tienes que dividir y unir a la cadena de len/2 veces. –

0

¿Quieres los dígitos ordenados? ¿O está intercambiando dígitos indexados impares/pares? Tu ejemplo no está del todo claro.

Ordenar:

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

s ahora es '1234'. El truco está aquí que la lista (cadena) lo divide en caracteres.

+1

Como nota, es más conciso solo hacer ''' join (ordenado (s))' y tan claro. –

+0

perdón por eso. Quiero intercambiar cada dos caracteres en la cadena. – cocobear

+0

¡Siempre me olvido ordenado (x)! Gracias. – Spacedman

1

bucle sobre la longitud de la cadena de dos en dos y de intercambio:

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) 

dando:

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

aspectos y no en las cadenas de longitud impar con una excepción IndexError.

6

La forma habitual de intercambiar a los elementos en Python es:

a, b = b, a 

por lo que parece a mí que usted acaba de hacer lo mismo con una rebanada extendida. Está un poco complicado porque las cadenas no son mutables lo que tiene que convertir en una lista y luego de vuelta a una cadena, pero lo que haría es:

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

ValueError para odd len (s)? –

+1

Desafortunadamente, no funcionará en cadenas de longitud irregular. –

+0

Paulo o Fabian, ¿qué te gustaría que ocurra para una entrada no válida además de arrojar una excepción? – Duncan

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

o

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

o si la cadena puede tener una longitud impar:

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

tenga en cuenta que esto no funcionará con versiones antiguas de Python (si no estoy confundiendo Olde r que 2.5).

El punto de referencia se ejecutó en python-2.7-8.fc14.1.x86_64 y una CPU Core 2 Duo 6400 con s=''*4.

+1

para odd len (s), el primero da 'IndexError: string index fuera de rango', el segundo chops último char. –

+1

@paulo: ¿y cuáles son los requisitos de OP para las cadenas de longitud impar? – SilentGhost

+0

@Paulo Scardine: tienes razón, pero la pregunta no era lo suficientemente específica. –

0

así:

>>> 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
re.sub(r'(.)(.)',r"\2\1",'abcdef1234') 

Sin embargo Re es un poco lento.

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

''.join(swap("abcdef1234")) 
2

Si el rendimiento o la elegancia no es un problema, y ​​lo que desea claridad y han hecho el trabajo a continuación, sólo tiene que utilizar esto:

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

Esto le permite cambiar o simplemente reemplazar caracteres o subcadena. Por ejemplo, para intercambiar 'ab' < -> 'de' en un texto:

_str = "abcdefabcdefabcdef" 
print swap(_str, 'ab','de') #decabfdecabfdecabf 
+2

¿No será esto extremadamente limitado en la aplicación? –

2

No hay necesidad de hacer una lista. Las siguientes obras para cuerdas, incluso de larga duración:

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

¿Qué pasa si la cadena tiene una longitud impar? –

0

una forma más:

>>> s='123456' 
>>> ''.join([''.join(el) for el in zip(s[1::2], s[0::2])]) 
'214365' 
0
>>> 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
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 
-1
#Works on even/odd size strings 
str = '2143657' 
newStr = '' 
for i in range(len(str)//2): 
    newStr += str[i*2+1] + str[i*2] 
if len(str)%2 != 0: 
    newStr += str[-1] 
print(newStr) 
+0

¡Bienvenido a Stack Overflow! Si bien este fragmento de código puede resolver la pregunta, incluida una explicación de * cómo * y * por qué * esto resuelve el problema [realmente ayudaría] (// meta.stackexchange.com/q/114762) para mejorar la calidad de su publicación. Recuerde que usted está respondiendo la pregunta a los lectores en el futuro, ¡no solo a la persona que pregunta ahora! Por favor [edite] su respuesta para agregar una explicación y dar una indicación de qué limitaciones y suposiciones se aplican. –

Cuestiones relacionadas