Простой Python — страница 7 из 66

Непрограммисты думают, что программисты хорошо разбираются в математике, потому что работают с числами. На самом деле большинство программистов работают с текстовыми строками гораздо чаще, чем с числами. Логическое (и креативное!) мышление для них зачастую гораздо важнее математических навыков.

Благодаря поддержке стандарта Unicode Python 3 может содержать символы любого языка мира, а также многие другие символы. Необходимость работы с этим стандартом была одной из причин изменения Python 2. Это хорошая причина использовать версию 3. Я буду применять стандарт Unicode лишь иногда, поскольку это может показаться сложным. В следующих примерах я буду использовать строки формата ASCII.

Строки являются первым примером последовательностей в Python. В частности, они представляют собой последовательности символов.

В отличие от других языков, в Python строки являются неизменяемыми. Вы не можете изменить саму строку, но можете скопировать части строк в другую строку, чтобы получить тот же эффект.

Скоро вы узнаете, как это делается.

Создаем строки с помощью кавычек

Строка в Python создается заключением символов в одинарные или двойные кавычки, как показано в следующем примере:

>>> 'Snap'

'Snap'

>>> "Crackle"

'Crackle'

Интерактивный интерпретатор выводит на экран строки в одинарных кавычках, но все они обрабатываются одинаково.

Зачем иметь два вида кавычек? Основная идея заключается в том, что вы можете создавать строки, содержащие кавычки. Внутри одинарных кавычек можно расположить двойные и наоборот:

>>> "'Nay,' said the naysayer."

"'Nay,' said the naysayer."

>>> 'The rare double quote in captivity: ".'

'The rare double quote in captivity: ".'

>>> 'A "two by four" is actually 1 1/2" × 3 1/2".'

'A "two by four is" actually 1 1/2" × 3 1/2".'

>>> "'There's the man that shot my paw!' cried the limping hound."

"'There's the man that shot my paw!' cried the limping hound."

Можно также использовать три одинарные (''') или три двойные кавычки ("""):

>>> '''Boom!'''

'Boom'

>>> """Eek!"""

'Eek!'

Тройные кавычки не очень полезны для таких коротких строк. Они обычно используются для того, чтобы создать многострочные строки, наподобие следующего классического стихотворения Эдварда Леара (Edward Lear):

>>> poem =··'''There was a Young Lady of Norway,

… Who casually sat in a doorway;

… When the door squeezed her flat,

… She exclaimed, "What of that?"

… This courageous Young Lady of Norway.'''

>>>

(Это стихотворение было введено в интерактивный интерпретатор, который поприветствовал нас символами >>> в первой строке и выводил символы … до тех пор, пока мы не ввели последние тройные кавычки и не перешли к следующей строке.)

Если бы вы попробовали создать стихотворение с помощью одинарных кавычек, Python начал бы волноваться, когда бы вы перешли к следующей строке:

>>> poem = 'There was a young lady of Norway,

··File "", line 1

····poem = 'There was a young lady of Norway,

············································^

SyntaxError: EOL while scanning string literal

>>>

Если внутри тройных кавычек располагается несколько строк, символы конца строки будут сохранены внутри нее. Если перед строкой или после нее находятся пробелы, они также будут сохранены:

>>> poem2 = '''I do not like thee, Doctor Fell.

…·····The reason why, I cannot tell.

…·····But this I know, and know full well:

…·····I do not like thee, Doctor Fell.

… '''

>>> print(poem2)

I do not like thee, Doctor Fell.

····The reason why, I cannot tell.

····But this I know, and know full well:

····I do not like thee, Doctor Fell.

>>>

Кстати, существует разница между выводом на экран с помощью функции print() и автоматическим выводом на экран с помощью интерактивного интерпретатора:

>>> poem2

'I do not like thee, Doctor Fell.\n····The reason why, I cannot tell.\n····But

this I know, and know full well: \n····I do not like thee, Doctor Fell.\n'

Функция print() извлекает кавычки из строк и выводит на экран их содержимое. Она предназначена для удобства пользователя. Эта функция любезно добавляет пробел между каждым выводимым объектом, а также символ новой строки в конце:

>>> print(99, 'bottles', 'would be enough.')

99 bottles would be enough.

Если вам не нужны пробелы или переход на новую строку, вскоре вы узнаете, как избежать их появления.

Интерпретатор выводит строку с одинарными кавычками и управляющими символами вроде \n, что объясняется в подразделе «Создаем управляющие символы с помощью символа \» далее в текущем разделе.

Наконец, вам может понадобиться работать с пустой строкой. В ней нет символов, но она совершенно корректна. Вы можете создать пустую строку с помощью любых упомянутых ранее кавычек:

>>> ''

''

>>> ""

''

>>> ''''''

''

>>> """"""

''

>>>

Зачем может понадобиться пустая строка? Иногда приходится компоновать строку из других строк и для этого нужно начать с чистого листа, то есть с пустой строки.

>>> bottles = 99

>>> base = ''

>>> base += 'current inventory: '

>>> base += str(bottles)

>>> base

'current inventory: 99'

Преобразование типов данных с помощью функции str()

Вы можете преобразовывать другие типы данных Python в строки с помощью функции str():

>>> str(98.6)

'98.6'

>>> str(1.0e4)

'10000.0'

>>> str(True)

'True'

В Python функция str() также используется для внутренних нужд, когда вы вызываете функцию print() для объектов, которые не являются строками, и при выполнении интерполяции строк, с которой вы познакомитесь в главе 7.

Создаем управляющие символы с помощью символа \

Python позволяет вам создавать управляющие последовательности внутри строк, чтобы добиться эффекта, который по-другому было бы трудно выразить. Размещая перед символом обратный слеш (\), вы наделяете этот символ особым значением. Наиболее распространена последовательность \n, которая означает переход на новую строку. С ее помощью вы можете создать многострочные строки из однострочных:

>>> palindrome = 'A man,\nA plan,\nA canal: \nPanama.'

>>> print(palindrome)

A man,

A plan,

A canal:

Panama.

Вы также увидите последовательность \t (табуляция), которая используется для выравнивания текста:

>>> print('\tabc')

····abc

>>> print('a\tbc')

a····bc

>>> print('ab\tc')

ab······c

>>> print('abc\t')

abc

В последней строке табуляция стоит в конце, ее вы, конечно, увидеть не можете.

Кроме того, вам могут понадобиться последовательности \' или \", чтобы поместить в строку одинарные или двойные кавычки, которые окружены таким же символом:

>>> print('\tabc')

····abc

>>> print('a\tbc')

a····bc

>>> print('ab\tc')

ab······c

>>> print('abc\t')

abc

А если вам нужен обратный слеш, просто напечатайте два:

>>> speech = 'Today we honor our friend, the backslash: \\.'

>>> print(speech)

Today we honor our friend, the backslash: \.

Объединяем строки с помощью символа +

Вы можете объединить строки или строковые переменные в Python с помощью оператора +, как показано далее:

>>> 'Release the kraken! ' + 'At once!'

'Release the kraken! At once!'

Можно также объединять строки (не переменные), просто расположив одну перед другой:

>>> "My word! " "A gentleman caller!"

'My word! A gentleman caller!'

Python не добавляет пробелы за вас при конкатенации строк, поэтому в предыдущем примере нужно явно добавить пробелы. Далее мы добавляем пробелы между каждым аргументом выражения print(), а также символ новой строки в конце:

>>> a = 'Duck.'

>>> b = a

>>> c = 'Grey Duck!'

>>> a + b + c

'Duck.Duck.Grey Duck!'

Размножаем строки с помощью символа *

Оператор * можно использовать для того, чтобы размножить строку. Попробуйте ввести в интерактивный интерпретатор следующие строки и посмотреть, что получится:

>>> start = 'Na ' * 4 + '\n'

>>> middle = 'Hey ' * 3 + '\n'

>>> end = 'Goodbye.'

>>> print(start + start + middle + end)

Извлекаем символ с помощью символов []

Для того чтобы получить один символ строки, задайте смещение внутри квадратных скобок после имени строки. Смещение первого (крайнего слева) символа равно 0, следующего — 1 и т. д. Смещение последнего (крайнего справа) символа может быть выражено как –1, поэтому вам не придется считать, в таком случае смещение последующих символов будет равно –2, –3 и т. д.:

>>> letters = 'abcdefghijklmnopqrstuvwxyz'

>>> letters[0]

'a'

>>> letters[1]

'b'

>>> letters[-1]

'z'

>>> letters[-2]

'y'

>>> letters[25]

'z'

>>> letters[5]

'f'

Если вы укажете смещение, равное длине строки или больше (помните, смещения лежат в диапазоне от 0 до длины строки –1), сгенерируется исключение:

>>> letters[100]

Traceback (most recent call last):

··File "", line 1, in 

IndexError: string index out of range

Индексирование работает и для других типов последовательностей (списков и кортежей), которые мы рассмотрим в главе 3.

Поскольку строки неизменяемы, вы не можете вставить символ непосредственно в строку или изменить символ по заданному индексу. Попробуем изменить слово Henny на слово Penny и посмотрим, что произойдет:

>>> name = 'Henny'

>>> name[0] = 'P'

Traceback (most recent call last):

··File "", line 1, in 

TypeError: 'str' object does not support item assignment

Вместо этого вам придется использовать комбинацию строковых функций вроде replace() или slice (ее вы увидите совсем скоро):

>>> name = 'Henny'

>>> name.replace('H', 'P')

'Penny'

>>> 'P' + name[1:]

'Penny'

Извлекаем подстроки с помощью оператора [start: end: step]

Из строки можно извлечь подстроку (часть строки) с помощью функции slice. Вы определяете slice с помощью квадратных скобок, смещения начала подстроки start и конца подстроки end, а также опционального размера шага step. Некоторые из этих параметров могут быть исключены. В подстроку будут включены символы, расположенные начиная с точки, на которую указывает смещение start, и заканчивая точкой, на которую указывает смещение end.

• Оператор [: ] извлекает всю последовательность от начала до конца.

• Оператор [start: ] извлекает последовательность с точки, на которую указывает смещение start, до конца.

• Оператор [: end] извлекает последовательность от начала до точки, на которую указывает смещение end минус 1.

• Оператор [start: end] извлекает последовательность с точки, на которую указывает смещение start, до точки, на которую указывает смещение end минус 1.

• Оператор [start: end: step] извлекает последовательность с точки, на которую указывает смещение start, до точки, на которую указывает смещение end минус 1, опуская символы, чье смещение внутри подстроки кратно step.

Как и ранее, смещение слева направо определяется как 0, 1 и т. д., а справа налево — как -1, -2 и т. д. Если вы не укажете смещение start, функция будет использовать в качестве его значения 0 (начало строки). Если вы не укажете смещение end, функция будет использовать конец строки.

Создадим строку, содержащую английские буквы в нижнем регистре:

>>> letters = 'abcdefghijklmnopqrstuvwxyz'

Использование простого двоеточия аналогично использованию последовательности 0: (целая строка):

>>> letters[: ]

'abcdefghijklmnopqrstuvwxyz'

Вот так можно получить все символы, начиная с 20-го и заканчивая последним:

>>> letters[20:]

'uvwxyz'

А теперь — начиная с 10-го и заканчивая последним:

>>> letters[10:]

'klmnopqrstuvwxyz'

А теперь получим символы с 12-го по 14-й (Python не включает символ, расположенный под номером, который указан последним):

>>> letters[12:15]

'mno'

Последние три символа:

>>> letters[-3:]

'xyz'

В следующем примере мы начинаем со смещения 18 и идем до четвертого с конца символа. Обратите внимание на разницу с предыдущим примером, где старт с позиции -3 получал символ х. В этом примере конец диапазона -3 означает, что последним будет символ по адресу -4 — w:

>>> letters[18:-3]

'stuvw'

В следующем примере мы получаем символы, начиная с шестого с конца и заканчивая третьим с конца:

>>> letters[-6:-2]

'uvwx'

Если вы хотите увеличить шаг, укажите его после второго двоеточия, как показано в нескольких следующих примерах.

Каждый седьмой символ с начала до конца:

>>> letters[::7]

'ahov'

Каждый третий символ, начиная со смещения 4 и заканчивая 19-м символом:

>>> letters[4:20:3]

'ehknqt'

Каждый четвертый символ, начиная с 19-го:

>>> letters[19::4]

'tx'

Каждый пятый символ от начала до 20-го:

>>> letters[:21:5]

'afkpu'

Опять же значение end должно быть на единицу больше, чем реальное смещение.

И это еще не все! Если задать отрицательный шаг, любезный Python будет двигаться в обратную сторону. В следующем примере движение начинается с конца и заканчивается в начале, ни один символ не пропущен:

>>> letters[-1::-1]

'zyxwvutsrqponmlkjihgfedcba'

Оказывается, можно добиться того же результата, использовав такой пример:

>>> letters[::-1]

'zyxwvutsrqponmlkjihgfedcba'

Операция slice более мягко относится к неправильным смещениям, чем поиск по индексу. Если указать смещение меньшее, чем начало строки, оно будет обрабатываться как 0, а если указать смещение большее, чем конец строки, оно будет обработано как –1. Это показано в следующих примерах.

Начиная с –50-го символа и до конца:

>>> letters[-50:]

'abcdefghijklmnopqrstuvwxyz'

Начиная с –51-го символа и заканчивая –50-м:

>>> letters[-51:-50]

''

От начала до 69-го символа:

>>> letters[:70]

'abcdefghijklmnopqrstuvwxyz'

Начиная с 70-го символа и заканчивая 70-м:

>>> letters[70:71]

''

Получаем длину строки с помощью функции len()

До этого момента мы использовали специальные знаки препинания вроде +, чтобы манипулировать строками. Но существует не так уж много подобных функций. Теперь мы начнем использовать некоторые встроенные функции Python: именованные фрагменты кода, которые выполняют определенные операции.

Функция len() подсчитывает символы в строке:

>>> len(letters)

26

>>> empty = ""

>>> len(empty)

0

Вы можете использовать функцию len() и для других типов последовательностей, что показано в главе 3.

Разделяем строку с помощью функции split()

В отличие от функции len() некоторые функции характерны только для строк. Для того чтобы использовать строковую функцию, введите имя строки, точку, имя функции и аргументы, которые нужны функции: строка. функция(аргументы). Более подробно о функциях мы будем говорить в разделе «Функции» главы 4.

Вы можете использовать встроенную функцию split(), чтобы разбить строку на список небольших строк, основываясь на разделителе. Со списками вы познакомитесь в следующей главе. Список — это последовательность значений, разделенных запятыми и окруженных квадратными скобками:

>>> todos = 'get gloves,get mask,give cat vitamins,call ambulance'

>>> todos.split(',')

['get gloves', 'get mask', 'give cat vitamins', 'call ambulance']

В предыдущем примере строка имела имя todos, а строковая функция называлась split() и получала один аргумент ','. Если вы не укажете разделитель, функция split() будет использовать любую последовательность пробелов, а также символы новой строки и табуляцию:

>>> todos.split()

['get', 'gloves,get', 'mask,give', 'cat', 'vitamins,call', 'ambulance']

Если вы вызываете функцию split без аргументов, вам все равно нужно добавлять круглые скобки — именно так Python узнает, что вы вызываете функцию.

Объединяем строки с помощью функции join()

Для вас не должен стать великим открытием тот факт, что функция join() является противоположностью функции split(): она объединяет список строк в одну строку. Вызов функции выглядит немного запутанно, поскольку сначала вы указываете строку, которая объединяет остальные, а затем — список строк для объединения: string.join(list). Для того чтобы объединить список строк lines, разделив их символами новой строки, вам нужно написать '\n'.join(lines). В следующем примере мы объединим несколько имен в список, разделенный запятыми и пробелами:

>>> crypto_list = ['Yeti', 'Bigfoot', 'Loch Ness Monster']

>>> crypto_string = ', '.join(crypto_list)

>>> print('Found and signing book deals:', crypto_string)

Found and signing book deals: Yeti, Bigfoot, Loch Ness Monster

Развлекаемся со строками

Python содержит большой набор функций для работы со строками. Рассмотрим принцип работы самых распространенных из них. Объектом для тестов станет следующая строка, содержащая текст бессмертного стихотворения What Is Liquid? Маргарет Кэвендиш (Margaret Cavendish), графини Ньюкасл:

>>> poem = '''All that doth flow we cannot liquid name

Or else would fire and water be the same;

But that is liquid which is moist and wet

Fire that property can never get.

Then 'tis not cold that doth the fire put out

But 'tis the wet that makes it die, no doubt.'''

Для начала получим первые 13 символов (их смещения лежат в диапазоне от 0 до 12):

>>> poem[:13]

'All that doth'

Сколько символов содержит это стихотворение? (Пробелы и символы новой строки учитываются.)

>>> len(poem)

250

Начинается ли стихотворение с буквосочетания All?

>>> poem.startswith('All')

True

Заканчивается ли оно буквосочетанием That's all, folks!?

>>> poem.endswith('That\'s all, folks!')

False

Найдем смещение первого включения слова the:

>>> word = 'the'

>>> poem.find(word)

73

А теперь — последнего:

>>> poem.rfind(word)

214

Сколько раз встречается трехбуквенное сочетание the?

>>> poem.count(word)

3

Являются ли все символы стихотворения буквами или цифрами?

>>> poem.isalnum()

False

Нет, в стихотворении имеются еще и знаки препинания.

Регистр и выравнивание

В этом разделе мы рассмотрим еще несколько примеров использования встроенных функций. В качестве подопытной выберем следующую строку:

>>> setup = 'a duck goes into a bar…'

Удалим символ «.» с обоих концов строки:

>>> setup.strip('.')

'a duck goes into a bar'


Поскольку строки неизменяемы, ни один из этих примеров не изменяет строку setup. Каждый пример просто берет значение переменной setup, выполняет над ним некоторое действие, а затем возвращает результат как новую строку.


Напишем первое слово с большой буквы:

>>> setup.capitalize()

'A duck goes into a bar…'

Напишем все слова с большой буквы:

>>> setup.title()

'A Duck Goes Into A Bar…'

Запишем все слова большими буквами:

>>> setup.upper()

'A DUCK GOES INTO A BAR…'

Запишем все слова маленькими буквами:

>>> setup.lower()

'a duck goes into a bar…'

Сменим регистры букв:

>>> setup.swapcase()

'a DUCK GOES INTO A BAR…'

Теперь мы поработаем с функциями выравнивания. Строка выравнивается внутри заданного количества пробелов (в данном примере 30).

Отцентруем строку в промежутке из 30 пробелов:

>>> setup.center(30)

'··a duck goes into a bar…···'

Выровняем ее по левому краю:

>>> setup.ljust(30)

'a duck goes into a bar…·····'

А теперь по правому:

>>> setup.rjust(30)

'·····a duck goes into a bar…'

О форматировании и преобразовании строк мы более подробно поговорим в главе 7. Там также будет затронуто использование символа % и функции format().

Заменяем символы с помощью функции replace()

Вы можете использовать функцию replace() для того, чтобы заменить одну подстроку другой. Вы передаете в эту функцию старую подстроку, новую подстроку и количество включений старой подстроки, которое нужно заменить. Если вы опустите последний аргумент, будут заменены все включения. В этом примере совпадает с заданным значением и заменяется следующая строка:

>>> setup.replace('duck', 'marmoset')

'a marmoset goes into a bar…'

Заменим максимум 100 включений:

>>> setup.replace('a ', 'a famous ', 100)

'a famous duck goes into a famous bar…'

Если вы точно знаете, какую подстроку или подстроки хотите изменить, функция replace() станет для вас хорошим выбором. Но будьте осторожны. Во втором примере, если бы мы заменили строку из одного символа 'а', а не строку из двух символов "а " (после а идет пробел), мы бы заменили символы 'а' и в середине слов:

>>> setup.replace('a', 'a famous', 100)

'a famous duck goes into a famous ba famousr…'

Иногда вам нужно убедиться, что подстрока является целым словом, началом слова и т. д. В этих случаях понадобятся регулярные выражения. Они подробно описаны в главе 7.

Больше действий со строками

В Python имеется гораздо больше функций для работы со строками, чем я сейчас описал. Некоторые из них мы рассмотрим в следующих главах, но вы можете найти описания их всех в стандартной документации (http://bit.ly/py-docs-strings).

Упражнения