September 20, 2022

41 вопрос работы со строками

1. Как проверить два объекта на идентичность?

Оператор is возвращает True в том случае, если в две переменные записана ссылка на одну и ту же область памяти. Именно об этом идёт речь при разговоре об «идентичности объектов».

Не стоит путать is и ==. Оператор == проверяет лишь равенство объектов.

animals           = ['python','gopher']
more_animals      = animals
print(animals == more_animals) #=> True
print(animals is more_animals) #=> True
even_more_animals = ['python','gopher']
print(animals == even_more_animals) #=> True
print(animals is even_more_animals) #=> False

Обратите внимание на то, что animals и even_more_animals не идентичны, хотя и равны друг другу.

Кроме того, существует функция id(), которая возвращает идентификатор адреса памяти, связанного с именем переменной. При вызове этой функции для двух идентичных объектов будет выдан один и тот же идентификатор.

name = 'object'
id(name)
#=> 4408718312

2. Как проверить то, что каждое слово в строке начинается с заглавной буквы?

Существует строковый метод istitle(), который проверяет, начинается ли каждое слово в строке с заглавной буквы.

print( 'The Hilton'.istitle() ) #=> True
print( 'The dog'.istitle() ) #=> False
print( 'sticky rice'.istitle() ) #=> False

3. Как проверить строку на вхождение в неё другой строки?

Существует оператор in, который вернёт True в том случае, если строка содержит искомую подстроку.

print( 'plane' in 'The worlds fastest plane' ) #=> True
print( 'car' in 'The worlds fastest plane' ) #=> False

4. Как найти индекс первого вхождения подстроки в строку?

Есть два метода, возвращающих индекс первого вхождения подстроки в строку. Это — find() и index(). У каждого из них есть определённые особенности.

Метод find() возвращает -1 в том случае, если искомая подстрока в строке не найдена.

'The worlds fastest plane'.find('plane') #=> 19
'The worlds fastest plane'.find('car') #=> -1

Метод index() в подобной ситуации выбрасывает ошибку ValueError.

'The worlds fastest plane'.index('plane') #=> 19
'The worlds fastest plane'.index('car') #=> ValueError: substring not found

5. Как подсчитать количество символов в строке?

Функция len() возвращает длину строки.

len('The first president of the organization..') #=> 41

6. Как подсчитать то, сколько раз определённый символ встречается в строке?

Ответить на этот вопрос нам поможет метод count(), который возвращает количество вхождений в строку заданного символа.

'The first president of the organization..'.count('o') #=> 3

7. Как сделать первый символ строки заглавной буквой?

Для того чтобы это сделать, можно воспользоваться методом capitalize().

'florida dolphins'.capitalize() #=> 'Florida dolphins'

8. Что такое f-строки и как ими пользоваться?

В Python 3.6 появилась новая возможность — так называемые «f-строки». Их применение чрезвычайно упрощает интерполяцию строк. Использование f-строк напоминает применение метода format().

При объявлении f-строк перед открывающей кавычкой пишется буква f.

name = 'Chris'
food = 'creme brulee'
f'Hello. My name is {name} and I like {food}.'
#=> 'Hello. My name is Chris and I like creme brulee'

9. Как найти подстроку в заданной части строки?

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

'the happiest person in the whole wide world.'.index('the',10,44)
#=> 23

Обратите внимание на то, что вышеприведённая конструкция возвращает 23, а не 0, как было бы, не ограничь мы поиск.

'the happiest person in the whole wide world.'.index('the')
#=> 0

10. Как вставить содержимое переменной в строку, воспользовавшись методом format()?

Метод format() позволяет добиваться результатов, сходных с теми, которые можно получить, применяя f-строки. Правда, я полагаю, что использовать format() не так удобно, так как все переменные приходится указывать в качестве аргументов format().

difficulty = 'easy'
thing = 'exam'
'That {} was {}!'.format(thing, difficulty)
#=> 'That exam was easy!'

11. Как узнать о том, что в строке содержатся только цифры?

Существует метод isnumeric(), который возвращает True в том случае, если все символы, входящие в строку, являются цифрами.

'80000'.isnumeric() #=> True

Используя этот метод, учитывайте то, что знаки препинания он цифрами не считает.

'1.0'.isnumeric() #=> False

12. Как разделить строку по заданному символу?

Здесь нам поможет метод split(), который разбивает строку по заданному символу или по нескольким символам.

'This is great'.split(' ')
#=> ['This', 'is', 'great']
'not--so--great'.split('--')
#=> ['not', 'so', 'great']

13. Как проверить строку на то, что она составлена только из строчных букв?

Метод islower() возвращает True только в том случае, если строка составлена исключительно из строчных букв.

'all lower case'.islower() #=> True
'not aLL lowercase'.islower() # False

14. Как проверить то, что строка начинается со строчной буквы?

Сделать это можно, вызвав вышеописанный метод islower() для первого символа строки.

'aPPLE'[0].islower() #=> True

15. Можно ли в Python прибавить целое число к строке?

В некоторых языках это возможно, но Python при попытке выполнения подобной операции будет выдана ошибка TypeError.

'Ten' + 10 #=> TypeError

16. Как «перевернуть» строку?

Для того чтобы «перевернуть» строку, её можно разбить, представив в виде списка символов, «перевернуть» список, и, объединив его элементы, сформировать новую строку.

''.join(reversed("hello world"))
#=> 'dlrow olleh'

17. Как объединить список строк в одну строку, элементы которой разделены дефисами?

Метод join() умеет объединять элементы списков в строки, разделяя отдельные строки с использованием заданного символа.

'-'.join(['a','b','c'])
#=> 'a-b-c'

18. Как узнать о том, что все символы строки входят в ASCII?

Метод isascii() возвращает True в том случае, если все символы, имеющиеся в строке, входят в ASCII.

print( 'Â'.isascii() ) #=> False
print( 'A'.isascii() ) #=> True

19. Как привести всю строку к верхнему или нижнему регистру?

Для решения этих задач можно воспользоваться методами upper() и lower(), которые, соответственно, приводят все символы строк к верхнему и нижнему регистрам.

sentence = 'The Cat in the Hat'
sentence.upper() #=> 'THE CAT IN THE HAT'
sentence.lower() #=> 'the cat in the hat'

20. Как преобразовать первый и последний символы строки к верхнему регистру?

Тут, как и в одном из предыдущих примеров, мы будем обращаться к символам строки по индексам. Строки в Python иммутабельны, поэтому мы будем заниматься сборкой новой строки на основе существующей.

animal = 'fish'
animal[0].upper() + animal[1:-1] + animal[-1].upper()
#=> 'FisH'

21. Как проверить строку на то, что она составлена только из прописных букв?

Имеется метод isupper(), который похож на уже рассмотренный islower(). Но isupper() возвращает True только в том случае, если вся строка состоит из прописных букв.

'Toronto'.isupper() #=> False
'TORONTO'.isupper() #= True

22. В какой ситуации вы воспользовались бы методом splitlines()?

Метод splitlines() разделяет строки по символам разрыва строки.

sentence = "It was a stormy night\nThe house creeked\nThe wind blew."
sentence.splitlines()
#=> ['It was a stormy night', 'The house creeked', 'The wind blew.']

23. Как получить срез строки?

Для получения среза строки используется синтаксическая конструкция следующего вида:

string[start_index:end_index:step]

Здесь step — это шаг, с которым будут возвращаться символы строки из диапазона start_index:end_index. Значение step, равное 3, указывает на то, что возвращён будет каждый третий символ.

string = 'I like to eat apples'
string[:6] #=> 'I like'
string[7:13] #=> 'to eat'
string[0:-1:2] #=> 'Ilk oetape' (каждый 2-й символ)

24. Как преобразовать целое число в строку?

Для преобразования числа в строку можно воспользоваться конструктором str().

str(5) #=> '5'

25. Как узнать о том, что строка содержит только алфавитные символы?

Метод isalpha() возвращает True в том случае, если все символы в строке являются буквами.

'One1'.isalpha() #=> False
'One'.isalpha() #=> True

26. Как в заданной строке заменить на что-либо все вхождения некоей подстроки?

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

sentence = 'Sally sells sea shells by the sea shore'
sentence.replace('sea', 'mountain')
#=> 'Sally sells mountain shells by the mountain shore'

27. Как вернуть символ строки с минимальным ASCII-кодом?

Если взглянуть на ASCII-коды элементов, то окажется, например, что прописные буквы имеют меньшие коды, чем строчные. Функция min() возвращает символ строки, имеющий наименьший код.

min('strings') #=> 'g'

28. Как проверить строку на то, что в ней содержатся только алфавитно-цифровые символы?

В состав алфавитно-цифровых символов входят буквы и цифры. Для ответа на этот вопрос можно воспользоваться методом isalnum().

'Ten10'.isalnum() #=> True
'Ten10.'.isalnum() #=> False

29. Как удалить пробелы из начала строки (из её левой части), из её конца (из правой части), или с обеих сторон строки?

Здесь нам пригодятся, соответственно, методы lstrip(), rstrip() и strip().

string = '  string of whitespace    '
string.lstrip() #=> 'string of whitespace    '
string.rstrip() #=> '  string of whitespace'
string.strip() #=> 'string of whitespace'

30. Как проверить то, что строка начинается с заданной последовательности символов, или заканчивается заданной последовательностью символов?

Для ответа на этот вопрос можно прибегнуть, соответственно, к методам startswith() и endswith().

city = 'New York'
city.startswith('New') #=> True
city.endswith('N') #=> False

31. Как закодировать строку в ASCII?

Метод encode() позволяет кодировать строки с использованием заданной кодировки. По умолчанию используется кодировка utf-8. Если некий символ не может быть представлен с использованием заданной кодировки, будет выдана ошибка UnicodeEncodeError.

'Fresh Tuna'.encode('ascii')
#=> b'Fresh Tuna'
'Fresh Tuna Â'.encode('ascii')
#=> UnicodeEncodeError: 'ascii' codec can't encode character '\xc2' in position 11: ordinal not in range(128)

32. Как узнать о том, что строка включает в себя только пробелы?

Есть метод isspace(), который возвращает True только в том случае, если строка состоит исключительно из пробелов.

''.isspace() #=> False
' '.isspace() #=> True
'   '.isspace() #=> True
' the '.isspace() #=> False

33. Что случится, если умножить некую строку на 3?

Будет создана новая строка, представляющая собой исходную строку, повторённую три раза.

'dog' * 3
# 'dogdogdog'

34. Как привести к верхнему регистру первый символ каждого слова в строке?

Существует метод title(), приводящий к верхнему регистру первую букву каждого слова в строке.

'once upon a time'.title() #=> 'Once Upon A Time'

35. Как объединить две строки?

Для объединения строк можно воспользоваться оператором +.

'string one' + ' ' + 'string two' 
#=> 'string one string two'

36. Как пользоваться методом partition()?

Метод partition() разбивает строку по заданной подстроке. После этого результат возвращается в виде кортежа. При этом подстрока, по которой осуществлялась разбивка, тоже входит в кортеж.

sentence = "If you want to be a ninja"
print(sentence.partition(' want '))
#=> ('If you', ' want ', 'to be a ninja')

37. Строки в Python иммутабельны. Что это значит?

То, что строки иммутабельны, говорит о том, что после того, как создан объект строки, он не может быть изменён. При «модификации» строк исходные строки не меняются. Вместо этого в памяти создаются совершенно новые объекты. Доказать это можно, воспользовавшись функцией id().

proverb = 'Rise each day before the sun'
print( id(proverb) )
#=> 4441962336
proverb_two = 'Rise each day before the sun' + ' if its a weekday'
print( id(proverb_two) )
#=> 4442287440

При конкатенации 'Rise each day before the sun' и ' if its a weekday' в памяти создаётся новый объект, имеющий новый идентификатор. Если бы исходный объект менялся бы, тогда у объектов был бы один и тот же идентификатор.

38. Если объявить одну и ту же строку дважды (записав её в 2 разные переменные) — сколько объектов будет создано в памяти? 1 или 2?

В качестве примера подобной работы со строками можно привести такой фрагмент кода:

animal = 'dog'
pet = 'dog'

При таком подходе в памяти создаётся лишь один объект. Когда я столкнулся с этим в первый раз, мне это не показалось интуитивно понятным. Но этот механизм помогает Python экономить память при работе с длинными строками.

Доказать это можно, прибегнув к функции id().

animal = 'dog'
print( id(animal) )
#=> 4441985688
pet = 'dog'
print( id(pet) )
#=> 4441985688

39. Как пользоваться методами maketrans() и translate()?

Метод maketrans() позволяет описать отображение одних символов на другие, возвращая таблицу преобразования.

Метод translate() позволяет применить заданную таблицу для преобразования строки.

# создаём отображение
mapping = str.maketrans("abcs", "123S")
# преобразуем строку
"abc are the first three letters".translate(mapping)
#=> '123 1re the firSt three letterS'

Обратите внимание на то, что в строке произведена замена символов a, b, c и s, соответственно, на символы 1, 2, 3 и S.

40. Как убрать из строки гласные буквы?

Один из ответов на этот вопрос заключается в том, что символы строки перебирают, пользуясь механизмом List Comprehension. Символы проверяют, сравнивая с кортежем, содержащим гласные буквы. Если символ не входит в кортеж — он присоединяется к новой строке.

string = 'Hello 1 World 2'
vowels = ('a','e','i','o','u')
''.join([c for c in string if c not in vowels])
#=> 'Hll 1 Wrld 2'

41. В каких ситуациях пользуются методом rfind()?

Метод rfind() похож на метод find(), но он, в отличие от find(), просматривает строку не слева направо, а справа налево, возвращая индекс первого найденного вхождения искомой подстроки.

story = 'The price is right said Bob. The price is right.'
story.rfind('is')
#=> 39

Итоги

Я часто объясняю одному продакт-менеджеру, человеку в возрасте, что разработчики — это не словари, хранящие описания методов объектов. Но чем больше методов помнит разработчик — тем меньше ему придётся гуглить, и тем быстрее и приятнее ему будет работаться. Надеюсь, теперь вы без труда ответите на рассмотренные здесь вопросы.