2011-12-01 20 views
9

Estoy tratando de convertir a 10000000C9ABCDEF10:00:00:00:c9:ab:cd:efInserción de un personaje a intervalos regulares en una lista

Esto es necesario porque 10000000C9ABCDEF formato es como veo HBA o Adaptadores de bus anfitrión cuando inicio mi matrices de almacenamiento. Pero los conmutadores SAN entienden la notación 10:00:00:00:c9:ab:cd:ef.

Sólo he podido lograr hasta el siguiente:

#script to convert WWNs to lowercase and add the :. 
def wwn_convert(): 
    while True: 
     wwn = (input('Enter the WWN or q to quit- ')) 
     list_wwn = list(wwn) 
     list_wwn = [x.lower() for x in list_wwn] 
     lower_wwn = ''.join(list_wwn) 
     print(lower_wwn) 
    if wwn == 'q': 
     break 

wwn_convert() 

Probé ':'.join, sino que inserta : después de cada carácter, por lo que obtener 1:0:0:0:0:0:0:0:c:9:a:b:c:d:e:f

Quiero que el .join que pasar por una bucle donde puedo decir algo como for i in range (0, 15, 2) para que inserte el : después de dos caracteres, pero no estoy seguro de cómo hacerlo. (Bueno que Python me ofrece al bucle en intervalos de 2 o cualquier número que yo quiero.)

Además, voy a estar agradecido si alguien podría dirigir a los punteros, donde pude guión esto mejor ...

Por favor ayuda.

estoy usando la versión 3.2.2 de Python en Windows 7 (64 bits)

Respuesta

2
>>> s = '10000000C9ABCDEF' 
>>> ':'.join([s[x:x+2] for x in range(0, len(s)-1, 2)]) 
'10:00:00:00:C9:AB:CD:EF' 

Explicación:

':'.join(...) devuelve una nueva cadena de inserción ':' entre las partes del iterable

s[x:x+2] devuelve una subcadena de longitud 2 a partir de las x de s

range(0, len(s) - 1, 2) devuelve una lista de números enteros con un paso de 2

por lo que la comprensión de la lista dividiría la cadena s en subcadenas de longitud 2, luego la join las pondría juntas pero insertando ':' entre ellas.

+1

¿Podría incluir una explicación del código? –

+0

Hola F.C., ¡Muchas gracias! Ustedes son muy útiles. –

6

Aquí hay otra opción:

>>> s = '10000000c9abcdef' 
>>> ':'.join(a + b for a, b in zip(*[iter(s)]*2)) 
'10:00:00:00:c9:ab:cd:ef' 

O aún más concisa:

>>> import re 
>>> ':'.join(re.findall('..', s)) 
'10:00:00:00:c9:ab:cd:ef' 
+0

¡La solución de expresiones regulares es muy hábil! – jathanism

+0

Hola, sí, la solución de expresiones regulares es realmente bonita ... gracias señor :) –

0

Se puede hacer uso de grouper receta de here.

from itertools import izip_longest 

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

Con esta función, el código se verá así:

def join(it): 
    for el in it: 
     yield ''.join(el) 

':'.join(join(grouper(2, s))) 

Funciona de la siguiente manera:

grouper(2,s) devuelve tuplas '1234...' -> ('1','2'), ('3','4') ...

def join(it) hace esto: ('1','2'), ('3','4') ... -> '12', '34' ...

':'.join(...) crea una cadena de iterador: '12', '34' ... -> '12:34...'

También, puede ser reescrita como:

':'.join(''.join(el) for el in grouper(2, s)) 
+0

+1 para usar la receta del mero itertools !! :) – jathanism

+0

-1 La solución es ridículamente complicada. –

+0

@JohnMachin No estoy de acuerdo. Además, agregaría que es bastante simple y directo. Utiliza una función estándar 'mero' del módulo' itertools', y lo que queda por hacer es unir las tuplas de salida por ''' .join', y unir las tuplas unidas por' ':'. Join'. No hay segmentos propensos a errores uno por uno, etc. ¡Simple y directo! (Aún así, la cuestión del gusto, creo). – ovgolovin

1

Creo que lo que le ayudaría a cabo la mayor parte es una construcción en Python llamada una rebanada. Creo que puede usarlos en cualquier objeto iterable, incluidas las cadenas, lo que los hace bastante útiles y, en general, es una muy buena idea para saber cómo usarlos.

>>> s = '10000000C9ABCDEF' 
>>> [s.lower()[i:i+2] for i in range(0, len(s)-1, 2)] 
['10', '00', '00', '00', 'c9', 'ab', 'cd', 'ef'] 
>>> ':'.join([s.lower()[i:i+2] for i in range(0, len(s)-1, 2)]) 
'10:00:00:00:c9:ab:cd:ef' 

Si desea leer un poco más sobre las rebanadas, son explicados muy bien in this question,, así como una parte de la actual python documentation.

+0

Esto es genial ... Ustedes son geniales ... Creo que muy pronto me voy a preguntar qué solución será mejor porque hay más de una forma de resolver las cosas en Python. Eso es increíble ... puede ser que el tiempo me diga cuál es el mejor método para usar en un problema dado ... –

+0

Es curioso que menciones eso ... Uno de los principios rectores de Python es que "debería haber uno- - y preferiblemente solo uno - forma obvia de hacerlo ". Es parte de lo que se llama el Zen de Python, puedes leerlo si usas 'import this' en Python Interpreter. Alternativamente, puede leerlo [aquí.] (Http://www.python.org/dev/peps/pep-0020/) –

1
>>> s='10000000C9ABCDEF' 
>>> si=iter(s) 
>>> ':'.join(c.lower()+next(si).lower() for c in si) 
>>> '10:00:00:00:c9:ab:cd:ef' 

En forma lambda:

>>> (lambda x: ':'.join(c.lower()+next(x).lower() for c in x))(iter(s)) 
'10:00:00:00:c9:ab:cd:ef' 
+0

wow, ¡¡tantas opciones !! Gracias Austin :) –

Cuestiones relacionadas