Ответ 1
Вопрос: Я использую 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(разделитель):
>>> ''.split(',') # No cuts
['']
>>> ','.split(',') # One cut
['', '']
>>> ',,'.split(',') # Two cuts
['', '', '']
Вопрос: И есть ли более удобный способ подсчета строк в строке?
Да, есть несколько простых способов. Один использует str.count(), а другой использует str.splitlines().
Оба способа дадут тот же ответ, если в последней строке отсутствует \n
.
Если окончательная новая строка отсутствует, подход str.splitlines даст точный ответ.
Более быстрый метод, который также является точным, использует метод подсчета, но затем корректирует его для окончательной новой строки:
>>> 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
Вопрос от @Kaz: Почему черты - это два очень разных алгоритма, обученных обувью в одну функцию?
Подпись для str.split составляет около 20 лет, а ряд API от той эпохи строго прагматичны. Хотя это и не идеально, подпись метода не является "ужасной". По большей части, выбор дизайна API Guido выдержал испытание временем.
Существующий API не имеет никаких преимуществ. Рассмотрим строки, такие как:
ps_aux_header = "USER PID %CPU %MEM VSZ"
patient_header = "name,age,height,weight"
Когда его просят разбить эти строки на поля,
люди склонны описывать как одно и то же английское слово "раскол".
Когда его просят читать код, например fields = line.split()
или fields = line.split(',')
,
люди склонны правильно интерпретировать заявления
как "разбивает линию на поля".
Microsoft Excel инструмент "текст-столбцы" сделал аналогичный выбор API и включает в себя оба алгоритма разделения в одном инструменте. Люди, похоже, мысленно моделируют разделение поля как единое понятие, даже если задействовано более одного алгоритма.