Вопрос: я использую 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(',')
['']
>>> ','.split(',')
['', '']
>>> ',,'.split(',')
['', '', '']
Вопрос: А есть ли более удобный способ подсчета строк в строке?
Да, есть несколько простых способов. Один использует str.count (), а другой - str.splitlines () . Оба способа дадут одинаковый ответ, если в последней строке не пропущен \n
. Если последний символ новой строки отсутствует, подход str.splitlines даст точный ответ. Более быстрый и точный метод использует метод count, но затем исправляет его для последней строки новой строки:
>>> data = '''\
Line 1
Line 2
Line 3
Line 4'''
>>> data.count('\n')
3
>>> len(data.splitlines())
4
>>> data.count('\n') + (not data.endswith('\n'))
4
Вопрос от @Kaz: какого черта два совершенно разных алгоритма объединены в одну функцию?
Сигнатуре 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 и объединяет оба алгоритма разделения в одном инструменте. Кажется, что люди мысленно моделируют разделение полей как единую концепцию, даже если задействовано более одного алгоритма.