2012-05-30 17 views
6

Problema: divida una cadena en una lista de palabras por un delimitador de caracteres pasados ​​como una lista.número de división de cadena

Cadena: "After the flood ... all the colors came out."

salida deseada: ['After', 'the', 'flood', 'all', 'the', 'colors', 'came', 'out']

he escrito la siguiente función - nota Soy consciente de que hay mejores maneras de dividir una cadena usando algunas de las pitones construidos en funciones, pero en aras de la aprendizaje pensé que iba a proceder de esta manera:

def split_string(source,splitlist): 
    result = [] 
    for e in source: 
      if e in splitlist: 
       end = source.find(e) 
       result.append(source[0:end]) 
       tmp = source[end+1:] 
       for f in tmp: 
        if f not in splitlist: 
         start = tmp.find(f) 
         break 
       source = tmp[start:] 
    return result 

out = split_string("After the flood ... all the colors came out.", " .") 

print out 

['After', 'the', 'flood', 'all', 'the', 'colors', 'came out', '', '', '', '', '', '', '', '', ''] 

no puedo entender por qué "salió" no se divide en "vino" y "fuera" como dos palabras separadas. Es como si el personaje de espacio en blanco entre las dos palabras estuviera siendo ignorado. Creo que el resto de la salida es basura que proviene del problema asociado con el problema "salió".

EDIT:

Seguí @ sugerencia de Ivc y se acercó con el siguiente código:

def split_string(source,splitlist): 
    result = [] 
    lasti = -1 
    for i, e in enumerate(source): 
     if e in splitlist: 
      tmp = source[lasti+1:i] 
      if tmp not in splitlist: 
       result.append(tmp) 
      lasti = i 
     if e not in splitlist and i == len(source) - 1: 
      tmp = source[lasti+1:i+1] 
      result.append(tmp) 
    return result 

out = split_string("This is a test-of the,string separation-code!"," ,!-") 
print out 
#>>> ['This', 'is', 'a', 'test', 'of', 'the', 'string', 'separation', 'code'] 

out = split_string("After the flood ... all the colors came out.", " .") 
print out 
#>>> ['After', 'the', 'flood', 'all', 'the', 'colors', 'came', 'out'] 

out = split_string("First Name,Last Name,Street Address,City,State,Zip Code",",") 
print out 
#>>>['First Name', 'Last Name', 'Street Address', 'City', 'State', 'Zip Code'] 

out = split_string(" After the flood ... all the colors came out...............", " ." 
print out 
#>>>['After', 'the', 'flood', 'all', 'the', 'colors', 'came', 'out'] 

Respuesta

2

usted parece estar esperando:

source = tmp[start:] 

Para modificar el source que el ciclo for exterior está interactuando sobre. No lo hará - ese bucle continuará sobre la cadena que le diste, no el objeto que esté utilizando ese nombre. Esto puede significar que el personaje que estás haciendo podría no estar en lo que queda de source.

En lugar de tratar de hacer eso, no perder de vista el índice actual en la cadena de esta manera:

for i, e in enumerate(source): 
    ... 

y lo que está realizando adiciones siempre será source[lasti+1:i], y sólo tiene que llevar un registro de lasti .

+1

Gracias a todos por las maravillosas soluciones. Me he ido con esto porque me obliga a aprender la lógica en lugar de usar funciones preconstruidas. Obviamente, si tuviera que escribir un código comercial, no volvería a inventar la rueda, pero con fines de aprendizaje iré con esta respuesta. Gracias por toda tu ayuda. – codingknob

3

No es necesario el llamado bucle interno. Sólo esto es suficiente:

def split_string(source,splitlist): 
    result = [] 
    for e in source: 
      if e in splitlist: 
       end = source.find(e) 
       result.append(source[0:end]) 
       source = source[end+1:] 
    return result 

se puede eliminar la "basura" (es decir, la cadena vacía), comprobando si la fuente [: fin] es una cadena vacía o no antes de añadirlo a la lista.

0

Por qué hay que hacer demasiadas cosas, Sólo este simple, tratar ..
str.split(strSplitter , intMaxSplitCount)intMaxSplitCount es opcional
En su caso, tienes que hacer algo de Houskeeping también, si se quiere evitar una ... es se puede reemplazar, como str.replace(".","", 3)3 es opcional, se reemplazará primeros 3 puntos solamente

por lo que en breve que tienes que hacer después,
print ((str.replace(".", "",3)).split(" ")) se imprimirá lo que usted desee

hice ejecución, Just Check Here,...

0
[x for x in a.replace('.', '').split(' ') if len(x)>0] 

Aquí 'a' es la cadena de entrada.

0

Una forma más sencilla, al menos se ve más simple ..

import string 

    def split_string(source, splitlist): 
     table = string.maketrans(splitlist, ' ' * len(splitlist)) 
     return string.translate(source, table).split() 

Puedes retirar string.maketrans y string.translate

2

Creo que si utiliza expresiones regulares se puede conseguir fácilmente si desea que sólo las palabras cadena dada arriba.

>>> import re 
>>> string="After the flood ... all the colors came out." 
>>> re.findall('\w+',string) 
['After', 'the', 'flood', 'all', 'the', 'colors', 'came', 'out'] 
Cuestiones relacionadas