2012-06-12 4 views
10

tengo una cadena concatenada como esto:La forma más rápida para dividir una cadena concatenada en una tupla e ignorar las cadenas vacías

my_str = 'str1;str2;str3;' 

y me gustaría aplicar split función a ella y luego convertir la lista dado lugar a una tupla, y deshacerse de cualquier cadena vacía el resultado de la split (nótese la última ';' al final)

Hasta el momento, estoy haciendo esto:

tuple(filter(None, my_str.split(';'))) 

¿Hay alguna manera más eficiente (en términos de velocidad y espacio) para hacerlo?

+0

@Levon, punto de toma, lo siento, Acabo de tomar un ejemplo nombre de la variable a toda prisa. Gracias. – MLister

+1

Por favor explique a qué se refiere exactamente con "mejor". – NPE

+0

1. ¿Pueden los segmentos vacíos solo ocurrir debido a un ';' adicional al final, o pueden existir cadenas vacías en el medio de la lista? 2. ¿Por qué quieres convertir el resultado en una tupla? Por lo general, simplemente usar la lista devuelta por 'str.split()' debería funcionar bien. –

Respuesta

7

Esa es una forma muy razonable de hacerlo. Algunas alternativas:

  • foo.strip(";").split(";") (si no habrá algún segmento vacíos dentro de la cadena)
  • [ x.strip() for x in foo.split(";") if x.strip() ] (para despojar a los espacios en blanco entre cada rebanada)

La forma "más rápida" para hacer esto dependerá de muchas cosas ... pero se puede experimentar fácilmente con %timeit de ipython:

 
In [1]: foo = "1;2;3;4;" 

In [2]: %timeit foo.strip(";").split(";") 
1000000 loops, best of 3: 1.03 us per loop 

In [3]: %timeit filter(None, foo.split(';')) 
1000000 loops, best of 3: 1.55 us per loop 
+0

Si esto solo se trata de rastrear ';', también puede usar 'str.rstrip()'. –

+0

Sí, definitivamente. 'strip' los eliminará de ambos extremos. –

1

utilización fraccionada y luego slici ng:

my_str.split(';')[:-1] 

o:

lis=[x for x in my_str.split(';') if x] 
+0

Creo que OP quiere una tupla como resultado, no una lista – Levon

2

Sí, es bastante lejos Pythonic para hacerlo. Si usted tiene un amor por las expresiones generadoras, también se podría reemplazar el filter() con:

tuple(part for part in my_str.split(';') if part) 

Esto tiene la ventaja de permitir un procesamiento adicional en cada parte en línea.

Es interesante observar que la documentación de str.split() dice:

... Si no se especifica SEP o es Ninguno, cualquier cadena de espacios en blanco es un separador y cadenas vacías se eliminan del resultado .

Me pregunto por qué este caso especial se llevó a cabo, sin que llegue a otros separadores ...

4

Si sólo espera una cadena vacía al final, que puede hacer:

a = 'str1;str2;str3;' 
tuple(a.split(';')[:-1]) 

o

tuple(a[:-1].split(';')) 
8

¿Qué le parece esto?

tuple(my_str.split(';')[:-1]) 
    ('str1', 'str2', 'str3') 

dividir la cadena en el carácter ;, y pasan todo fuera de las subseries (excepto la última, la cadena vacía) para crear la tupla a tupla resultado.

2

Trate tuple(my_str.split(';')[:-1])

Cuestiones relacionadas