Eu estou usando split('\n')
para obter linhas em uma seqüência de caracteres, e descobriu que ''.split()
retorna uma lista vazia,, []
enquanto ''.split('\n')
retorna ['']
. Existe alguma razão específica para essa diferença?
E existe alguma maneira mais conveniente de contar linhas em uma string?
Respostas:
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).Este primeiro modo é útil quando os dados são alinhados em colunas com quantidades variáveis de espaço em branco. Por exemplo:
O segundo modo é útil para dados delimitados, como CSV, onde vírgulas repetidas indicam campos vazios. Por exemplo:
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 :
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: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:
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()
oufields = 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.
fonte
Parece simplesmente ser do jeito que deve funcionar, de acordo com a documentação :
Portanto, para tornar mais claro, a
split()
função implementa dois algoritmos de divisão diferentes e usa a presença de um argumento para decidir qual deles executar. Isso pode ser porque permite otimizar um para nenhum argumento mais do que aquele com argumentos; Eu não sei.fonte
.split()
sem parâmetros tenta ser inteligente. Ele se divide em qualquer espaço em branco, guias, espaços, feeds de linha etc., e também pula todas as seqüências vazias como resultado disso.Essencialmente,
.split()
sem parâmetros são usados para extrair palavras de uma string, ao contrário de.split()
parâmetros que apenas pegam uma string e a dividem.Essa é a razão da diferença.
E sim, contar linhas dividindo não é uma maneira eficiente. Conte o número de feeds de linha e adicione um se a sequência não terminar com um feed de linha.
fonte
Use
count()
:fonte
cat file
distorce sua linha de comando e o subversion reclama. vi sempre acrescenta um.Observe a última frase.
Para contar linhas, você pode simplesmente contar quantas
\n
:A última parte leva em consideração a última linha que não termina
\n
, mesmo que isso signifique issoHello, World!
eHello, World!\n
tenha a mesma contagem de linhas (o que para mim é razoável); caso contrário, você pode simplesmente adicionar1
à contagem de\n
.fonte
Para contar linhas, você pode contar o número de quebras de linha:
Editar :
A outra resposta com o built-in
count
é mais adequada, na verdadefonte
count
, os bools são adicionáveis (na verdade, eles são subclassesint
), então o genexp pode ser escrito comosum(s == "\n" for s in the_string)
.