Pergunta: Estou usando split ('\ n') para obter linhas em uma string e descobri que '' .split () retorna lista vazia [], enquanto '' .split ('\ n') retorna [''] .
O método str.split () possui dois algoritmos. Se nenhum argumento for fornecido, ele será dividido em execuções repetidas de espaço em branco. No entanto, se um argumento for fornecido, ele será tratado como um delimitador único, sem execuções repetidas.
No caso de dividir uma sequência vazia, o primeiro modo (sem argumento) retornará uma lista vazia porque o espaço em branco é consumido e não há valores para colocar na lista de resultados.
Por outro lado, o segundo modo (com um argumento como \n
) produzirá o primeiro campo vazio. Considere que, se você tivesse escrito '\n'.split('\n')
, obteria dois campos (uma divisão, duas metades).
Pergunta: Existe alguma razão específica para essa diferença?
Este primeiro modo é útil quando os dados são alinhados em colunas com quantidades variáveis de espaço em branco. Por exemplo:
>>> 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']
O segundo modo é útil para dados delimitados, como CSV, onde vírgulas repetidas indicam campos vazios. Por exemplo:
>>> 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']
Observe que o número de campos de resultados é um maior que o número de delimitadores. Pense em cortar uma corda. Se você não fizer cortes, você terá uma peça. Fazendo um corte, dá dois pedaços. Fazendo dois cortes, dá três pedaços. E assim é com o método str.split (delimitador) do Python :
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
Pergunta: E existe alguma maneira mais conveniente de contar linhas em uma string?
Sim, existem algumas maneiras fáceis. Um usa str.count () e o outro usa str.splitlines () . Ambas as formas fornecerão a mesma resposta, a menos que a linha final esteja ausente \n
. Se a nova linha final estiver ausente, a abordagem str.splitlines fornecerá a resposta precisa. Uma técnica mais rápida, que também é precisa, usa o método count, mas o corrige para a nova linha 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
Pergunta do @Kaz: Por que diabos existem dois algoritmos muito diferentes em uma única função?
A assinatura do str.split tem cerca de 20 anos e várias APIs daquela época são estritamente pragmáticas. Embora não seja perfeita, a assinatura do método também não é "terrível". Na maioria das vezes, as opções de design da API do Guido resistiram ao teste do tempo.
A API atual não está isenta de vantagens. Considere cadeias de caracteres como:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
Quando solicitados a dividir essas cadeias em campos, as pessoas tendem a descrever as duas usando a mesma palavra em inglês "dividir". Quando solicitados a ler códigos como fields = line.split()
ou fields = line.split(',')
, as pessoas tendem a interpretar corretamente as instruções como "divide uma linha em campos".
A ferramenta de texto para colunas do Microsoft Excel fez uma escolha de API semelhante e incorpora os dois algoritmos de divisão na mesma ferramenta. As pessoas parecem modelar mentalmente a divisão de campos como um conceito único, embora mais de um algoritmo esteja envolvido.