Строки в python
>>> 'string'
'string'
>>> "string"
'string'
>>> '''string'''
'string'
>>> """string"""
'string'
>>> ''
''
>>> ""
''
>>> ''''''
''
>>> """"""
''
>>> text = '''There was a Young Lady of Norway,
... Who casually sat in a doorway;
... When the door squeezed her flat.'''
>>> text
'There was a Young Lady of Norway,\nWho casually sat in a doorway;\nWhen the door squeezed her flat.\n'
>>> print(text)
There was a Young Lady of Norway,
Who casually sat in a doorway;
When the door squeezed her flat.
>>> print ('Give', "us", '''some''', """space""")
Give us some space
Объединение строк
>>> "My word! " "A gentleman caller!"
'My word! A gentleman caller!'
>>> "Alas! ""The kraken!"
'Alas! The kraken!'
>>> vowels = ( 'a'
... "e" '''i'''
... 'o' """u"""
... )
>>> vowels
'aeiou'
>>> a = 'Duck'
>>> b = a
>>> c = 'Grey Duck!'
>>> a + b + c
'DuckDuckGrey Duck!'
>>> print(a, b, c)
Duck Duck Grey Duck!
Извлекание символа из строки
Индексирование
>>> letters = 'abcdefghijklmnopqrstuvwxyz'
>>> letters[0]
'a'
>>> letters[1]
'b'
>>> letters[-1]
'z'
>>> letters[-2]
'y'
>>> letters[25]
'z'
>>> letters[100]
Traceback (most recent call last):
File "<input>", line 1, in <module>
letters[100]
~~~~~~~^^^^^
IndexError: string index out of range
Поскольку строки неизменяемы, нельзя вставить символ в строку или изменить символ по заданному индексу:
>>> name = 'Henny'
>>> name[0] = 'P'
Traceback (most recent call last):
File "<input>", line 1, in <module>
name[0] = 'P'
~~~~^^^
TypeError: 'str' object does not support item assignment
Поэтому это делается так:
>>> name = 'Henny'
>>> name.replace('H', 'P')
'Penny'
>>> 'P' + name[1:]
'Penny'
Слайсы
>>> letters = 'abcdefghijklmnopqrstuvwxyz'
>>> letters[:]
'abcdefghijklmnopqrstuvwxyz'
>>> letters[20:]
'uvwxyz'
>>> letters[10:]
'klmnopqrstuvwxyz'
>>> letters[12:15]
'mno'
>>> letters[-3:]
'xyz'
>>> letters[18:-3]
'stuvw'
>>> letters[-6:-2]
'uvwx'
>>> letters[::7]
'ahov'
>>> letters[4:20:3]
'ehknqt'
>>> letters[19::4]
'tx'
>>> letters[:21:5]
'afkpu'
>>> letters[-1::-1]
'zyxwvutsrqponmlkjihgfedcba'
>>> letters[::-1]
'zyxwvutsrqponmlkjihgfedcba'
Если указать смещение меньшее, чем начало строки, оно будет обрабатываться как 0, а если указать смещение большее, чем конец строки, оно будет обработано как -1:
>>> letters[-50:]
'abcdefghijklmnopqrstuvwxyz'
>>> letters[-51:-50]
''
>>> letters[:70]
'abcdefghijklmnopqrstuvwxyz'
>>> letters[70:71]
''
Типы строк
В Python существует несколько особых типов строк, определяемых буквой, стоящей перед первой кавычкой.
С буквы u начинается строка из символов Unicode - та же простая строка.
С буквы f/F начинается f-строка, которая используется для форматирования.
С буквы r/R начинается необработанная строка - предотвращает создание управляющих символов в строке.
Возможна и комбинация fr/fR/Fr/FR, с которой начинается необработанная f-строка.
С буквы b начинается значение объекта типа bytes.
Необработанные строки (r/R)
В необработанной строке escape-символы не работают:
>>> info = r'Type a \n to get a new line in a normal string'
>>> info
'Type a \\n to get a new line in a normal string'
# Интерактивный интерпретатор добавил доп. обратный слэш
>>> print(info)
Type a \n to get a new line in a normal string
В необработанных строках работают все реальные (а не выполненные с помощью
последовательности ‘\n’) переходы на новую строку:
>>> poem = r'''Boys and girls, come out to play.
... The moon doth shine as bright as day.'''
>>> poem
'Boys and girls, come out to play.\nThe moon doth shine as bright as day.'
>>> print(poem)
Boys and girls, come out to play.
The moon doth shine as bright as day.
Глобальная функция .format()
Позволяет форматировать строки.
user_name = input()
user_lastname = input()
info = 'My name and lastname is {name} {lastname}'.format(
name=user_name,
lastname=user_lastname
)
# My name and lastname is John Doe
Либо, если знаешь порядок переменных, можно просто нумеровать их:
user_name = input()
user_lastname = input()
info = 'My name and lastname is {0} {1}'.format(
user_name,
user_lastname
)
# My name and lastname is John Doe
# можно повторять переменные:
info = 'My name and lastname is {0} {0} {0} {1}'.format(
user_name,
user_lastname
)
# My name and lastname is John John Doe
В случае с передачей в скобках только одной переменной, можно в фигурных скобках не писать ничего:
meds = 'Pharmaceutical Industries Ltd.'
print('Sum {}'.format(meds))
# Sum Pharmaceutical Industries Ltd.
Предпочтительность юзания .format() вместо f-строк
Хоть f-строки быстрее, но в некоторых местах предпочтительнее .format() :
ip_template = '{0}.{1}.{2}.{3}'
octets = []
for octet_number in range(4):
while True:
input_octet = int(input(f'Enter the octet #{octet_number + 1}: '))
if input_octet in range(0, 256):
octets.append(input_octet)
break
else:
print('Error: octet must be in range 0-255')
print(ip_template.foprmat(*octets))
# * позволяет не писать такое:
print(ip_template.format(octets[0], octets[1], octets[2], octets[3]))
P.S. Лично я решил бы эту задачу так:
ip_address = []
for octet_number in range(4):
while True:
input_octet = int(input(f'Enter the octet #{octet_number + 1}: '))
if input_octet in range(0, 256):
ip_address.append(input_octet)
break
else:
print('Error: octet must be in range 0-255')
ip_address_str = '.'.join(map(str, ip_address))
print(ip_address_str)
Вот где еще предпочтительнее использовать .format(). Когда на строку ссылается переменная (“шаблон” какой-нибудь, idk) (congrats_template
, в этом случае):
congrats_template = 'С днём рождения, {name}! С {age}-летием тебя!'
people = 'Иван Иванов, Петя Петров, Лена Ленова'.split(', ')
ages = '20 30 18'.split()
for person, age in zip(people, ages):
print(congrats_template.format(
name=person,
age=age
))
Подстановки (placeholders)
Общий синтаксис плейсхолдера:
{:placeholder}
В зависимости от плейсхолдера можно добавлять доп. параметры. Например, для форматирования float чисел можно:
{:[количество_символов][запятая][.число_знаков_в_дробной_части] плейсхолдер}
- Сначала идет двоеточие (:)
- Опциональный символ-заполнитель (по умолчанию ’ ’), которым заполняется строка, если ее длина меньше, чем мин_ширина
- Опциональный символ выравнивания. В этот раз вариантом по умолчанию является выравнивание по левому краю. Символ ’<’ означает выравнивание по левому краю, символ ’>’ - по правому, а символ ’^’ означает выравнивание по центру
- Опциональный знак для чисел. Отсутствие значения приведет к тому, что знак будет отображаться только для отрицательных чисел. Символ ’ ’ означает, что для отрицательных чисел будет добавляться знак -, а для положительных - пробел (’ ’)
- Опциональное поле мин_ширина. Необязательный символ (’.’) используется для отделения значений полей мин_ширина и макс_символы
- Опциональное поле макс_символы
- Тип преобразования
s: для вставки строк
welcome = "Hello {:s}"
name = "Tom"
formatted_welcome = welcome.format(name)
# Hello Tom
В качестве результата метод format() возвращает новую отформатированную строку.
d: для вставки целых чисел
source = "{:d} символов"
number = 5
target = source.format(number)
# 5 символов
Если форматируемое число больше 999, то мы можем указать в определении плейсхолдера, что мы хотим использовать запятую в качестве разделителя разрядов:
source = "{:,d} символов"
# 5,000 символов
Причем плейсхолдеры можно использовать и в f-строках:
n = 5000
source = f"{n:,d} символов"
# 5,000 символов
f: для вставки дробных чисел
Также можно определить через точку количество знаков в дробной части)
Для дробных чисел, то есть таких, которые представляют тип float, перед кодом плейсхолдера после точки можно указать, сколько знаков в дробной части мы хотим вывести:
number = 23.8589578
print("{:.2f}".format(number)) # 23.86
print("{:.3f}".format(number)) # 23.859
print("{:.4f}".format(number)) # 23.8590
print("{:,.2f}".format(10001.23554)) # 10,001.24
Еще один параметр позволяет установить минимальную ширину форматируемого значения в символах:
print("{:10.2f}".format(23.8589578)) # 23.86
print("{:8d}".format(25)) # 25
Аналогичный пример с f-строками:
n1 = 23.8589578
print(f"{n1:10.2f}") # 23.86
n2 = 25
print(f"{n2:8d}") # 25
%: умножает значение на 100 и добавляет знак процента
number = .12345
print("{:%}".format(number)) # 12.345000%
print("{:.0%}".format(number)) # 12%
print("{:.1%}".format(number)) # 12.3%
print(f"{number:%}") # 12.345000%
print(f"{number:.0%}") # 12%
print(f"{number:.1%}") # 12.3%
e: выводит число в экспоненциальной записи
number = 12345.6789
print("{:e}".format(number)) # 1.234568e+04
print("{:.0e}".format(number)) # 1e+04
print("{:.1e}".format(number)) # 1.2e+04
print(f"{number:e}") # 1.234568e+04
print(f"{number:.0e}") # 1e+04
print(f"{number:.1e}") # 1.2e+04
f-strings
Быстрее, чем .format() .
Не стоит, например, математические выражения всякие писать внутри {} - лучше юзать переменные.
user_name = input()
user_lastname = input()
info = 'My name and lastname is {user_name} {user_lastname}'
# My name and lastname is John John Doe
Я так юзаю обычно f-строки:
print(f'Фамилия: Иванов'
f'\nИмя: {name}'
f'\nУлица: Пушкина'
f'\nДом: {houseNumber}\n')
Для f-строк используется такой же язык форматирования, как и для .format():
>>> thing = 'wereduck'
>>> place = 'werepond'
>>> f'The {thing:>20} is in the {place:.^20}'
'The wereduck is in the ......werepond......'
В Python 3.8 появилась возможность юзать такие конструкции:
>>> f'{thing =}, {place =}'
"thing ='wereduck', place ='werepond'"
>>> f'{thing[-4:] =}, {place.title() =}'
"thing[-4:] ='duck', place.title() ='Werepond'"
# P.S.
# Можно комбинировать форматирование из плейсхолдеров с этой штукой:
>>> f'{thing = :>4.4}'
'thing = were'
Методы и функции строк
Строковые функции юзаются так:
string.function(args)
.join() - Объединение списка строк в одну
Список с str item-ами:
symbol_list = ['A', 'm', 'e', 'n', 'd']
print(''.join(symbol_list))
# Amend
print('.'.join(symbol_list))
# A.m.e.n.d
print(', '.join(symbol_list))
# A, m, e, n, d
Список с int item-ами:
ip_address = [12, 23, 34, 231]
ip_address_str = '.'.join(map(str, ip_address))
print(ip_address_str)
# or
print('.'.join(str(num) for num in ip_address))
# 12.23.34.231
Простое соединение строк:
str_1 = 'Sum Pharmaceutical '
str_2 = 'Industries Ltd.'
print(''.join([str_1, str_2]))
# Sum Pharmaceutical Industries Ltd.
Результат будет тот же, что и при конкатенации (
print(str_1 + str_2
), но метод с .join() быстрее.
.split() - Разделение
Делит строку по пробелам (по дефолту).
text = 'One Two Three'
# или ДАЖЕ с кучей пробелов - всё будет норм:
text = 'One Two Three'
words = text.split()
# ['One', 'Two', 'Three']
Но можно и передать в скобках произвольный разделитель:
text = 'One, Two, Three'
words = text.split(', ')
# ['One', 'Two', 'Three']
Если нужно строку с числами превратить в список с int числами, то:
numbers_str = '6 4 32 234 11'
numbers = [int(item) for item in numbers_str.split()]
# [6, 4, 32, 234, 11]
# либо (чтобы понятнее стало):
numbers_str = '6 4 32 234 11'
numbers_list = numbers_str.split()
numbers = [int(item) for item in numbers_list]
# [6, 4, 32, 234, 11]
.replace() - Замена подстрок
>>> setup = "a duck goes into a bar..."
>>> setup.replace('duck', 'marmoset')
'a marmoset goes into a bar...'
>>> setup
'a duck goes into a bar...' # не меняется
Замена до 100 экземпляров:
>>> setup = "a duck a goes a into a a bar... a a "
>>> setup.replace('a ', 'THE ', 100)
'THE duck THE goes THE into THE THE bar... THE THE '
>>> setup
'a duck a goes a into a a bar... a a '
.strip(), .lstrip(), .rstrip() - Подрезание
Функция .strip() удаляет символы с обоих концов строки, .lstrip() - только в начале, а .rstrip() - только в конце.
>>> world = " earth "
>>> world.strip()
'earth'
>>> world.strip(' ')
'earth'
>>> world.lstrip()
'earth '
>>> world.rstrip()
' earth'
Если искомого символа в строке нет → ничего не происходит:
>>> world.strip('!')
' earth '
Можно указать последовательность символов:
>>> blurt = "What the...!!?"
>>> blurt.strip('.?!')
'What the'
# Либо так:
>>> import string
>>> string.whitespace
' \t\n\r\x0b\x0c'
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> blurt = "What the...!!?"
>>> blurt.strip(string.punctuation)
'What the'
>>> prospector = "What in tarnation ...??!!"
>>> prospector.strip(string.whitespace + string.punctuation)
'What in tarnation'
.find() и .index() для поиска подстрок в строке
Есть два метода поиска смещения подстроки - .find() и .index().
У каждого метода имеется возможность начинать поиск или с начала, или с конца. В случае если подстрока присутствует в строке, они работают одинаково. Если подстрока не найдена, метод .find() возвращает −1, а метод .index() генерирует исключение.
>>> poem = 'All that the flow we the liquid the or else would fire and water be the same'
>>> len(poem)
76
>>> word = 'the'
>>> poem.find(word)
9
>>> poem.index(word)
9
>>> poem.rfind(word)
68
>>> poem.rindex(word)
68
# А если подстроки нет?
>>> word = "duck"
>>> poem.find(word)
-1
>>> poem.rfind(word)
-1
>>> poem.index(word)
Traceback (most recent call last):
File "<input>", line 1, in <module>
poem.index(word)
ValueError: substring not found
>>> poem.rindex(word)
Traceback (most recent call last):
File "<input>", line 1, in <module>
poem.rindex(word)
ValueError: substring not found
.center(), .ljust(), rjust() - Выравнивание
Строка выравнивается в пределах указанного общего кол-ва пробелов:
>>> setup = "a duck goes into a bar..."
>>> 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...'
Методы строк: startswith, endswith, upper, lower, title
.endswith() и .startswith()
Если нужно, например, проверить, заканчивается ли строка на ‘abc’:
if string.endswith('abc'):
print('yesssss')
# или НЕ
if not string.endswith('abc'):
print('noooo')
Тоже самое с началом:
if string.startswith('ad'):
print('yesssss')
# или НЕ
if not string.startswith('ad'):
print('noooo')
Можно также в скобки startswith() и endswith() передать список с помощью tuple:
extensions = ['.txt', '.docx']
spec_chars = list('#@№$%^&\\*()')
# можно было и без списка - tuple с символами и так обходится.
# Но так поструктурированнее и логичнее как-то.
input_filename = input('Enter the filename: ')
if input_filename.startswith(tuple(spec_chars)):
print('\nError: The name starts with spec chars 😱.')
elif not input_filename.endswith(tuple(extensions)):
print('\nError: Invalid file extension. Expected .txt or .docx.')
else:
print('\nThe filename is correct.')
.lower(), .upper(), .title()
Наглядно:
string = 'adJjkjOPjkjkKVXCVX0svmx,vmx'
string.lower()
# adjjkjopjkjkkvxcvx0svmx,vmx
string.upper()
# ADJJKJOPJKJKKVXCVX0SVMX,VMX
Кстати, методы можно записывать друг за другом:
string = 'ad JjkjO Pjkjk KV XCVX0s vmx,vmx'
words = string.lower().split()
# ['ad', 'jjkjo', 'pjkjk', 'kv', 'xcvx0s', 'vmx,vmx']
Сделать первые буквы слов заглавными может .title():
string = 'Кажется, я забыл выключить утюг.'.title()
# Кажется, Я Забыл Выключить Утюг.
Старый стиль форматирования (%)
Имеет форму строка % данные
, где внутри строки находятся интерполяционные последовательности. Самая простая последовательность - это символ % и буква. Буква указывает на тип данных, которые должны быть отформатированы.
Интерполяционная последовательность | Тип данных |
---|---|
%s | Строка |
%d | int в десятичной СС |
%x | int в шестнадцатеричной СС |
%o | int в восьмеричной СС |
%f | float в десятичной СС |
%g | float в восьмеричной СС |
%e | float в шестнадцатеричной СС |
%% | Символ % |
Можно юзать %s для любого типа данных - python отформатирует их как строку без доп. пробелов.
int
>>> '%s' % 42
'42'
>>> '%d' % 42
'42'
>>> '%x' % 42
'2a'
>>> '%o' % 42
'52'
float
>>> '%s' % 7.03
'7.03'
>>> '%f' % 7.03
'7.030000'
>>> '%e' % 7.03
'7.030000e+00'
>>> '%g' % 7.03
'7.03'
int и символ %
>>> '%d%%' % 100
'100%'
str+int
>>> actor = 'Richard Gere'
>>> cat = 'Chester'
>>> weight = 28
>>> "My wife's favorite actor is %s" % actor
"My wife's favorite actor is Richard Gere"
>>> "Our cat %s weighs %s pounds" % (cat, weight)
'Our cat Chester weighs 28 pounds'
Последовательность %s внутри строки означает, что нужно интерполировать строку. Количество использованных символов %, естественно, должно совпадать с количеством
объектов, расположенных после %. Один элемент, такой как actor, располагается сразу после символа %. Если таких объектов несколько, они должны быть сгруппированы в кортеж, то есть их нужно заключить в скобки, разделив запятыми. Например, (cat, weight)
.
Несмотря на то что переменная weight целочисленная, последовательность %s
внутри строки преобразует ее в строку.
Подробнее про синтаксис
- Сначала идет %
- Опциональный символ выравнивания
Ничего или ’+’ означают выравнивание по правому краю, а ’−’ - по левому - Опциональное поле мин_ширина, в котором указывается длина строки
- Опциональный символ ’.’, разделяющий поля мин_ширина и макс_символы;
- Опциональное поле макс_символы
Используется в том случае, если тип преобразования s. Указывается, сколько символов значения нужно вывести на экран.
Если тип преобразования f, в этом поле указывается точность (сколько символов выводится после десятичной точки) - символ, определяющий тип преобразования (см. таблицу в начале)
Примеры для строки (%s)
>>> thing = 'woodchuck'
>>> '%s' % thing
'woodchuck'
>>> '%12s' % thing
' woodchuck'
>>> '%+12s' % thing
' woodchuck'
>>> '%-12s' % thing
'woodchuck '
>>> '%.3s' % thing
'woo'
>>> '%12.3s' % thing
' woo'
>>> '%-12.3s' % thing
'woo '
Примеры для float (%f)
>>> thing = 98.6
>>> '%f' % thing
'98.600000'
>>> '%12f' % thing
' 98.600000'
>>> '%+12f' % thing
' +98.600000'
>>> '%-12f' % thing
'98.600000 '
>>> '%.3f' % thing
'98.600'
>>> '%12.3f' % thing
' 98.600'
>>> '%-12.3f' % thing
'98.600 '
Примеры для int (%d)
>>> thing = 9876
>>> '%d' % thing
'9876'
>>> '%12d' % thing
' 9876'
>>> '%+12d' % thing
' +9876'
>>> '%-12d' % thing
'9876 '
>>> '%.3d' % thing
'9876'
>>> '%12.3d' % thing
' 9876'
>>> '%-12.3d' % thing
'9876 '
Для целых чисел конструкция %+12d
заставляет вывести знак числа, при этом строки формата, содержащие конструкцию .3
, ни на что не влияют, поскольку предназначены для чисел с плавающей точкой.
Соус: Книга “Простой Python” → Глава 5. “Текстовые строки”