2010-07-15 12 views

Respuesta

33

Supongamos longitud de la cadena es siempre un número par,

>>> s = '12345678' 
>>> t = iter(s) 
>>> '-'.join(a+b for a,b in zip(t, t)) 
'12-34-56-78' 

El t también se pueden eliminar con

>>> '-'.join(a+b for a,b in zip(s[::2], s[1::2])) 
'12-34-56-78' 

El algoritmo es agrupar la cadena en pares, y luego unirse ellos con el carácter -.

El código está escrito así. En primer lugar, se divide en dígitos impares e incluso dígitos.

>>> s[::2], s[1::2] 
('1357', '2468') 

Entonces the zip function se utiliza para combinarlos en un iterable de tuplas.

>>> list(zip(s[::2], s[1::2])) 
[('1', '2'), ('3', '4'), ('5', '6'), ('7', '8')] 

Pero las tuplas no son lo que queremos. Esto debería ser una lista de cadenas. Este es el propósito de la lista por comprensión

>>> [a+b for a,b in zip(s[::2], s[1::2])] 
['12', '34', '56', '78'] 

Finalmente utilizamos str.join() combinar la lista.

>>> '-'.join(a+b for a,b in zip(s[::2], s[1::2])) 
'12-34-56-78' 

La primera parte del código es la misma idea, pero consume menos memoria si la cadena es larga.

+1

¿Puedes explicar la parte de la cremallera? ¿Qué está haciendo eso? – root

+0

¿Qué sucede si la longitud de s es impar? –

+0

@Ham: el último personaje desaparecerá. – kennytm

29
>>> s = 'aabbccdd' 
>>> '-'.join(s[i:i+2] for i in range(0, len(s), 2)) 
'aa-bb-cc-dd' 
+2

¿Qué pasa con las secuencias de longitud impar? –

+3

Considero esto más pitónico que el vudú zip en la respuesta aprobada. El hecho de que no necesites usar range (len (string)) para los loops en python, no significa que tengas que ir a inventar locuras solo para evitarlo. – jsbueno

+2

@hamish: mantiene el último carácter e inserta un guión delante de él.¿No es un comportamiento deseado? – SilentGhost

0

Este delineador hace el truco. Soltará el último carácter si tu cadena tiene un número impar de caracteres.

"-".join([''.join(item) for item in zip(mystring1[::2],mystring1[1::2])]) 
+0

La respuesta de SilentGhost es mejor. Pero me gusta probar el zipping ... – chryss

2

Si desea conservar el último carácter si la cadena tiene una longitud impar, entonces se puede modificar la respuesta de KennyTM utilizar itertools.izip_longest:

>>> s = "aabbccd" 
>>> from itertools import izip_longest 
>>> '-'.join(a+b for a,b in izip_longest(s[::2], s[1::2], fillvalue="")) 
'aa-bb-cc-d' 

o

>>> t = iter(s) 
>>> '-'.join(a+b for a,b in izip_longest(t, t, fillvalue="")) 
'aa-bb-cc-d' 
0

Aquí es un modo de comprensión de lista con valor condicional que depende del módulo de enumeración, el último carácter impar estará solo en el grupo:

for s in ['aabbccdd','aabbccdde']: 
    print(''.join([ char if not ind or ind % 2 else '-' + char 
        for ind,char in enumerate(s) 
        ] 
       ) 
     ) 
""" Output: 
aa-bb-cc-dd 
aa-bb-cc-dd-e 
""" 
Cuestiones relacionadas