Питання: Я використовую 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']
Зауважте, кількість полів результатів на один більший, ніж кількість роздільників. Подумайте перерізати мотузку. Якщо ви не робите порізів, у вас є одна деталь. Зробивши один зріз, дають дві частини. Зробивши два надрізи, дає три шматки. І так це з методом str.split (роздільник) Python :
>>> ''.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"
На запитання про те, щоб розбити ці рядки на поля, люди прагнуть описати обидва, використовуючи одне й те саме англійське слово "split". На запит прочитати такий код, як fields = line.split()
абоfields = line.split(',')
, люди прагнуть правильно інтерпретувати висловлювання як "розбиває рядок на поля".
Інструмент " Текст до стовпців" Microsoft Excel зробив аналогічний вибір API та включає обидва алгоритми розбиття в одному інструменті. Здається, люди подумки моделюють поділ поля як єдину концепцію, навіть якщо задіяно більше одного алгоритму.