Pregunta: Estoy usando split ('\ n') para obtener líneas en una cadena, y descubrí que '' .split () devuelve una lista vacía [], mientras que '' .split ('\ n') devuelve [''] .
El método str.split () tiene dos algoritmos. Si no se dan argumentos, se divide en ejecuciones repetidas de espacios en blanco. Sin embargo, si se proporciona un argumento, se trata como un delimitador único sin ejecuciones repetidas.
En el caso de dividir una cadena vacía, el primer modo (sin argumento) devolverá una lista vacía porque se come el espacio en blanco y no hay valores para poner en la lista de resultados.
Por el contrario, el segundo modo (con un argumento como \n
) producirá el primer campo vacío. Considere que si hubiera escrito '\n'.split('\n')
, obtendría dos campos (uno dividido, le da dos mitades).
Pregunta: ¿Hay alguna razón específica para tal diferencia?
Este primer modo es útil cuando los datos se alinean en columnas con cantidades variables de espacios en blanco. Por ejemplo:
>>> data = '''\
Shasta California 14,200
McKinley Alaska 20,300
Fuji Japan 12,400
'''
>>> for line in data.splitlines():
print line.split()
['Shasta', 'California', '14,200']
['McKinley', 'Alaska', '20,300']
['Fuji', 'Japan', '12,400']
El segundo modo es útil para datos delimitados, como CSV, donde las comas repetidas denotan campos vacíos. Por ejemplo:
>>> data = '''\
Guido,BDFL,,Amsterdam
Barry,FLUFL,,USA
Tim,,,USA
'''
>>> for line in data.splitlines():
print line.split(',')
['Guido', 'BDFL', '', 'Amsterdam']
['Barry', 'FLUFL', '', 'USA']
['Tim', '', '', 'USA']
Tenga en cuenta que el número de campos de resultado es uno mayor que el número de delimitadores. Piensa en cortar una cuerda. Si no haces cortes, tienes una sola pieza. Haciendo un corte, da dos piezas. Haciendo dos cortes, da tres piezas. Y así es con el método str.split (delimitador) de Python :
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
Pregunta: ¿Y hay alguna forma más conveniente de contar líneas en una cadena?
Sí, hay un par de formas fáciles. Uno usa str.count () y el otro usa str.splitlines () . Ambas formas darán la misma respuesta a menos que a la línea final le falte el \n
. Si falta la nueva línea final, el enfoque str.splitlines dará la respuesta precisa. Una técnica más rápida que también es precisa utiliza el método de conteo pero luego lo corrige para la nueva línea final:
>>> data = '''\
Line 1
Line 2
Line 3
Line 4'''
>>> data.count('\n') # Inaccurate
3
>>> len(data.splitlines()) # Accurate, but slow
4
>>> data.count('\n') + (not data.endswith('\n')) # Accurate and fast
4
Pregunta de @Kaz: ¿Por qué diablos hay dos algoritmos muy diferentes en una sola función?
La firma de str.split tiene aproximadamente 20 años, y varias API de esa época son estrictamente pragmáticas. Si bien no es perfecto, la firma del método tampoco es "terrible". En su mayor parte, las opciones de diseño de API de Guido han resistido la prueba del tiempo.
La API actual no está exenta de ventajas. Considere cadenas como:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
Cuando se les pide que dividan estas cadenas en campos, las personas tienden a describir ambas utilizando la misma palabra en inglés, "dividir". Cuando se les pide que lean códigos como fields = line.split()
o fields = line.split(',')
, las personas tienden a interpretar correctamente las declaraciones como "divide una línea en campos".
La herramienta de texto a columnas de Microsoft Excel hizo una elección de API similar e incorpora ambos algoritmos de división en la misma herramienta. Las personas parecen modelar mentalmente la división de campos como un concepto único a pesar de que está involucrado más de un algoritmo.