company_banner

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

Автор оригинала: Chris
  • Перевод
Я начал вести список наиболее часто используемых функций, решая алгоритмические задачи на LeetCode и HackerRank.

Быть хорошим программистом — это не значит помнить все встроенные функции некоего языка. Но это не означает и того, что их запоминание — бесполезное дело. Особенно — если речь идёт о подготовке к собеседованию.

Хочу сегодня поделиться со всеми желающими моей шпаргалкой по работе со строками в Python. Я оформил её в виде списка вопросов, который использую для самопроверки. Хотя эти вопросы и не тянут на полноценные задачи, которые предлагаются на собеседованиях, их освоение поможет вам в решении реальных задач по программированию.



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

Итоги


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

Уважаемые читатели! Что, касающееся обработки строк в Python, вы посоветовали бы изучить тем, кто готовится к собеседованию?

RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Похожие публикации

Комментарии 40

    0
    По 37. Не понимаю пример (вроде и так понятно, что объекты разные). Можете назвать пример языков, где бы с похожим формированием строк у двух объектов ссылки бы шли на одну область памяти?
      0
      Если записывать как a = a + b, то очевидно. А если a += 1, то уже может быть не так очевидно
      >>> a = 'dog'
      >>> b = 'dog'
      >>> a is b # id(a) == id(b)
      True
      >>> a += ' cat'
      >>> a
      'dog cat'
      >>> b
      'dog'
      >>> a is b
      False
      


      Кстати, немного удивил этот способ экономии памяти на одинаковых строках. Но уверен у разработчиков python есть аргументы почему это сделано так.
        +1

        string interning, реализовано во многих языках

          0

          Да, но в python это распространяется на все неизменяемые объекты


          >>> import sys
          >>> sys.getrefcount(1)
          815
          >>> sys.getrefcount(0)
          1215
          >>> sys.getrefcount('')
          455
          >>> sys.getrefcount(())
          8771
            0
            На самом деле нет.
            Даже для чисел это работает только для небольших:
            >>> a=123
            >>> b=a+1
            >>> c=b-1
            >>> id(a),id(c)
            (140730597696992, 140730597696992)
            >>> a=12345
            >>> b=a+1
            >>> c=b-1
            >>> id(a),id(c)
            (2568231156208, 2568231156400)
            
        0

        В Java точно так же. Строки неизменяемые, и литералы хранятся в специальной области хипа (heap), называемой String Pool.
        В момент присвоения строкового литерала компилятор ищет такую же строку в String Pool и возвращает ссылку на существующий объект либо создаёт новый. Это называется "интернирование" (interning).
        Следует, однако, различать литералы и строки, созданные с использованием оператора new. Во втором случае всегда создаётся новый объект в куче (не в String Pool). К тому же у строк есть метод intern(), но детали здесь не буду приводить.

        +4

        По 37. Чего-то пример вообще не в тему.
        ИМХО, правильней проверка так:


        proverb = 'Rise each day before the sun'
        id(proverb) # -> 5691328
        proverb += 'b'
        id(proverb) # -> 7467712
          +11
          16. Переворот строки
          Намного изящней смотрится способ с переворотом строки срезом:
          print("hello world"[::-1])  # dlrow olleh
            0
            +1
            Пользуюсь таким
            0
            Я бы добавил еще иллюстрацию задачи с определением набора уникальных символов в строке, пересечения и объединения таких наборов из нескольких строк.
            Задачу удобно решать перейдя от строки к множествам
            first_str = 'aabbcdef'
            second_str = "cdefghhh"
            
            first_set = set(first_str)    # символы без повторов
            second_set = set(second_str)  # символы без повторов
            print(first_set, second_set)
            # {'c', 'a', 'd', 'e', 'f', 'b'} {'c', 'g', 'd', 'e', 'h', 'f'}
            
            # Определеим пересечение и объединение
            intersection_set = first_set & second_set   # пересечение
            union_set = first_set | second_set          # объединение
            print(intersection_set, union_set)
            # {'c', 'd', 'e', 'f'} {'c', 'a', 'd', 'g', 'e', 'h', 'f', 'b'}
            
            # вернемся к сортированным строкам
            intersection_str = ''.join(sorted(intersection_set))
            union_str = ''.join(sorted(union_set))
            print(intersection_str, union_str)  # cdef abcdefgh

            Еще распространенная задача — выделение из текста отдельных слов.
            Вот пример решения регулярным выражением — stackoverflow.com/questions/6181763/converting-a-string-to-a-list-of-words

            В 23 пункт по срезам добавьте, что step может быть отрицательным, и тогда перебор идет в обратном порядке, от конца к началу — это иногда очень удобно, например как в моем примере выше с переворотом строки.
              +1
              Вместо {sign for sign in first_str} достаточно set(first_str)
                0
                Действительно, ступил, исправил выше.
                Спасибо за дополнение!
              +1
              40. Я бы использовал regex, компактней и быстрее работает:
              >>> import re
              >>> string = 'Hello 1 World 2'
              >>> re.sub(r'[aeiou]', '', string)
              'Hll 1 Wrld 2'

                +1
                Насколько быстрее?
                +1
                12. Как разделить строку по заданному символу?
                Ещё есть интересный метод — rsplit(разбивает строку справа налево). Буквально на днях понадобилось мне разбить строки вида «1:2:3:4:5:data» по последнему разделителю. Сначала пробовал так «str.split(':',-1)» — не получилось. Погуглил — нашел rsplit. Да, это есть в офф. документации. Но в процессе гугления понял, что много народа об этом не знают.
                  0
                  Можно было и через split, но -1 нужно было в индекс среза ставить:
                  mystr = '1:2:3:4:5:data'
                  print(mystr.split(':')[-1])  # data
                  Но на длинных строках это будет не оптимально, rsplit() с ограничением 1 будет лучше:
                  print(mystr.rsplit(':', 1)[-1])  # data

                    +1
                    «Разбить по последнему двоеточию» — это не то же самое, что «взять текст после последнего двоеточия».
                      0
                      Ну может не так выразился.
                  +2

                  41 тривиальный ответ на бестолковые вопросы о том о сём.
                  Вы бы уж до 42 дотянули, что ли…
                  Мне кажется вопросов действительно о строках тут мало. Тут многое про множества, парадигмы протоколов… но как-то неявно, неглубоко.
                  К примеру, интересно было бы упомянуть про различие между isdigit, isnumeric и isdecimal хотя бы в виде ссылки. Это может оказаться любопытным.
                  Также часто новички путаются со строковыми литералами в коде.


                  Там много нюансов и их можно было осветить, это было бы действительно информативно.
                  a = 'это '\
                  'одна строка'
                  b = ('а кто '
                  f'{random.choice(["не ", ""])}угадает '
                  'что здесь присвоится?'
                  )

                  Про юникод-символы много всякого можно рассказать вроде такого:


                  'копе\N{combining acute accent}йка \N{RUBLE SIGN} бережет'
                    0

                    Вариант B использовал для длинных строковых литералов, чтобы влезть в максимальную ширину строки. Выглядит лучше чем A, по-моему.

                    +1
                    В .format() тоже можно как в f-строках
                    difficulty = 'easy'
                    thing = 'exam'
                    'That {thingy} was {how_hard}!'.format(thingy=thing, how_hard=difficulty)
                    #=> 'That exam was easy!'
                      +2
                      ''.join([c for c in string if c not in vowels])

                      А зачем тут список делать, если достаточно просто итерируемого объекта? Просто generator expression будет достаточно: ''.join(c for c in string if c not in vowels)

                        0

                        как раз сейчас учу пайтон, спасибо, за суперинформативный для меня лично пост)

                          0
                          36. partition() не просто разбивает строку и возвращает результат в виде кортежа, partition возвращает кортеж ровно из трёх элементов — подстрока до первого вхождения разделителя, разделитель, подстрока после первого вхождения разделителя.
                            +1
                            27 — тут будет точнее сказать, что вернется символ с минимальным кодом в utf-8 (Судя по f-строкам речь идет про python3). Как следствие можно то же самое применить и к символам, которых нет в ascii
                              0

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


                              'string one' + ' ' + 'string two'

                              Зачем делать действие в таком виде? А если нужно будет сложить десяток строк? Конкатенация для каждого из плюсов создаёт промежуточный объект и является самым медленным способом работы со строками.
                              В данном случае лучше использовать либо метод " ".join(), куда вставить список строк для объединения, либо использовать упомянутый в пункте 8 синтаксис f-строк: f"{} {}".

                                +1
                                Зачем делать действие в таком виде?


                                Наглядно же. И требуется обьединить 2 строки, а не N.
                                –2
                                По 16 пункту, ИМХО, намного проще заюзать отрицательный срез
                                s = "Test string"
                                print(s[::-1]) # gnirts tseT
                                
                                  –2
                                  Для того чтобы «перевернуть» строку, её можно разбить, представив в виде списка символов, «перевернуть» список, и, объединив его элементы, сформировать новую строку.

                                  'hello world'[::-1]
                                    0
                                    Это конечно все прекрасно, но нельзя в виде спойлеров сделать решения?
                                    А так спасибо автору, хотя с некоторыми примерами не согласен
                                      0
                                      Очень много светлого текста на светло фоне:
                                        0
                                        В части 37 пункта, мог бы добавить, что, если смотреть укороченную строку, равную другой строке с тем же содержанием, то id изменится.
                                          0
                                          11)
                                          Есть 3 метода определения состоит ли строка лишь из цифр:
                                          isnumeric(), isdigit(), isdecimal()
                                          На символы неарабских цифр или дробей они дают разные ответы.
                                          Если проверка именно на арабские цифры, то лучше использовать isdecimal()

                                          vals = ("038", "੦੩੮", "038",
                                                  "⁰³⁸", "⒊⒏", "⓪③⑧",
                                                  "↉⅛⅘", "ⅠⅢⅧ", "⑩⑬㊿", "壹貳參",
                                                  "38.0", "-38"
                                                  )
                                          
                                          for s in vals:
                                              print(s, s.isnumeric(), s.isdigit(), s.isdecimal())

                                            +1
                                            Как раз арабских цифр в вашем примере и не хватает, добавьте "۰۳۸"
                                              +1
                                              К сожалению отредактировать я не смогу.
                                              038 — арабские цифры
                                              ۰۳۸ — арабские цифры
                                              Справедливости ради, подставил второе значение и был слегка удивлен результатом, у всех методов результат True.
                                            –1
                                            В #40 квадратные скобки, в принципе, не особо-то и нужны (generator тоже iterable)
                                            ''.join(c for c in string if c not in vowels)
                                              0
                                              Хм, полагаю, "-1" за то, что я проглядел в комментариях аналогичный ответ или есть какие-то другие причины?
                                              0
                                              (40) будет читабельнее через translate:
                                              >>> string = 'Hello 1 World 2'
                                              >>> mapping = str.maketrans("", "", "aeiou");
                                              >>> string.translate(mapping)
                                              'Hll 1 Wrld 2'
                                                +1
                                                32. Как узнать о том, что строка включает в себя только пробелы?

                                                Не пробелы, а пробельные символы (whitespace).
                                                >>> '\r  \n'.isspace()
                                                True


                                                Для объединения строк можно воспользоваться оператором +.
                                                'string one' + ' ' + 'string two'
                                                #=> 'string one string two'

                                                Пример неудачен, со строковыми литералами это делать бессмысленно, можно обойтись без плюсов:
                                                >>> 'string one'  ' ' 'string two'
                                                'string one string two'


                                                Стоит добавить что в py3.9 у строк есть весьма полезные методы .removeprefix() и .removesuffix()
                                                  0
                                                  Упомянутые в конце новые методы в 3.9 могут некоторым показаться излишними, ведь есть lstrip, rstrip, однако не все знают (и я до некоторых пор был в числе незнающих), что lstrip и rstrip работают иначе. Например:
                                                  "foooofobar".lstrip('foo') # 'bar'
                                                  "foooofobar".removeprefix('foo') # 'oofobar'

                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                Самое читаемое