Я использую split('\n')
для получения строк в одной строке и обнаружил, что ''.split()
возвращает пустой список []
, а ''.split('\n')
возвращает ['']
. Есть ли конкретная причина такой разницы?
А есть ли более удобный способ подсчета строк в строке?
Ответы:
Метод str.split () имеет два алгоритма. Если аргументы не указаны, он разбивается на повторяющиеся пробелы. Однако, если указан аргумент, он рассматривается как единственный разделитель без повторных запусков.
В случае разделения пустой строки первый режим (без аргументов) вернет пустой список, потому что пробелы съедены и в список результатов нет значений для добавления.
Напротив, второй режим (с таким аргументом, как
\n
) создаст первое пустое поле. Представьте, что если бы вы написали'\n'.split('\n')
, вы бы получили два поля (одно разделенное, дает вам две половины).Этот первый режим полезен, когда данные выровнены в столбцы с переменным количеством пробелов. Например:
>>> 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']
Второй режим полезен для данных с разделителями, таких как CSV, где повторяющиеся запятые обозначают пустые поля. Например:
>>> 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']
Обратите внимание, количество полей результатов на единицу больше, чем количество разделителей. Подумайте о перерезании веревки. Если вы не сделаете разрезов, у вас будет один кусок. Сделав один разрез, получается две штуки. Сделав два надреза, получается три штуки. То же самое и с методом Python str.split (delimiter) :
>>> ''.split(',') # No cuts [''] >>> ','.split(',') # One cut ['', ''] >>> ',,'.split(',') # Two cuts ['', '', '']
Да, есть несколько простых способов. Один использует str.count (), а другой - str.splitlines () . Оба способа дадут одинаковый ответ, если в последней строке не пропущен
\n
. Если последний символ новой строки отсутствует, подход str.splitlines даст точный ответ. Более быстрый и точный метод использует метод count, но затем исправляет его для последней строки новой строки:>>> 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
Сигнатуре str.split около 20 лет, и ряд API того времени строго прагматичен. Хотя сигнатура метода не идеальна, она не является «ужасной». По большей части выбор дизайна API Гвидо выдержал испытание временем.
Текущий API не лишен преимуществ. Рассмотрим такие строки, как:
ps_aux_header = "USER PID %CPU %MEM VSZ" patient_header = "name,age,height,weight"
Когда их просят разбить эти строки на поля, люди склонны описывать их одним и тем же английским словом «split». Когда их просят прочитать код, такой как
fields = line.split()
илиfields = line.split(',')
, люди склонны правильно интерпретировать утверждения как «разбивает строку на поля».Инструмент преобразования текста в столбцы Microsoft Excel сделал аналогичный выбор API и объединяет оба алгоритма разделения в одном инструменте. Кажется, что люди мысленно моделируют разделение полей как единую концепцию, даже если задействовано более одного алгоритма.
источник
Это , кажется, просто так , как это должно работать, в соответствии с документацией :
Итак, чтобы было понятнее,
split()
функция реализует два разных алгоритма разделения и использует наличие аргумента, чтобы решить, какой из них запустить. Это может быть связано с тем, что он позволяет оптимизировать не более аргументов, чем тот, который имеет аргументы; Я не знаю.источник
.split()
без параметров пытается умничать. Он разбивается на любые пробелы, табуляции, пробелы, переводы строк и т. Д., А также пропускает все пустые строки в результате этого.>>> " fii fbar \n bopp ".split() ['fii', 'fbar', 'bopp']
По сути,
.split()
без параметров используются для извлечения слов из строки, в отличие от.split()
параметров, которые просто берут строку и разбивают ее.В этом причина разницы.
И да, подсчет строк путем разделения - неэффективный способ. Подсчитайте количество переводов строки и добавьте один, если строка не заканчивается переводом строки.
источник
Использование
count()
:s = "Line 1\nLine2\nLine3" n_lines = s.count('\n') + 1
источник
cat file
искажает вашу командную строку и жалуется подрывная деятельность. vi всегда добавляет один.>>> print str.split.__doc__ S.split([sep [,maxsplit]]) -> list of strings Return a list of the words in the string S, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done. If sep is not specified or is None, any whitespace string is a separator and empty strings are removed from the result.
Обратите внимание на последнее предложение.
Чтобы подсчитать строки, вы можете просто посчитать, сколько
\n
их:line_count = some_string.count('\n') + some_string[-1] != '\n'
Последняя часть учитывает последнюю строку, которая не заканчивается
\n
, даже если это означает, чтоHello, World!
и уHello, World!\n
них одинаковое количество строк (что для меня разумно), в противном случае вы можете просто добавить1
к количеству\n
.источник
Чтобы подсчитать строки, вы можете подсчитать количество разрывов строк:
n_lines = sum(1 for s in the_string if s == "\n") + 1 # add 1 for last line
Редактировать :
Другой ответ со встроенным
count
более подходящим, на самом делеисточник
count
, bools можно добавлять (фактически, они являются подклассомint
), поэтому genexp можно записать какsum(s == "\n" for s in the_string)
.