Как найти второй символ в строке python

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

Синтаксис

string.find(substring,start,end)

Метод find принимает три параметра:

  • substring (символ/подстрока) — подстрока, которую нужно найти в данной строке.
  • start (необязательный) — первый индекс, с которого нужно начинать поиск. По умолчанию значение равно 0.
  • end (необязательный) — индекс, на котором нужно закончить поиск. По умолчанию равно длине строки.

Параметры, которые передаются в метод, — это подстрока, которую требуются найти, индекс начала и конца поиска. Значение по умолчанию для начала поиска — 0, а для конца — длина строки.

В этом примере используем метод со значениями по умолчанию.

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


>>> string = "Добро пожаловать!"
>>> print("Индекс первой буквы 'о':", string.find("о"))
Индекс первой буквы 'о': 1

Поиск не с начала строки с аргументом start

Можно искать подстроку, указав также начальное положение поиска.

В этом примере обозначим стартовое положение значением 8 и метод начнет искать с символа с индексом 8. Последним положением будет длина строки — таким образом метод выполнит поиска с индекса 8 до окончания строки.


>>> string = "Специалисты назвали плюсы и минусы Python"
>>> print("Индекс подстроки 'али' без учета первых 8 символов:", string.find("али", 8))
Индекс подстроки 'али' без учета первых 8 символов: 16

Поиск символа в подстроке со start и end

С помощью обоих аргументов (start и end) можно ограничить поиск и не проводить его по всей строке. Найдем индексы слова «пожаловать» и повторим поиск по букве «о».


>>> string = "Добро пожаловать!"
>>> start = string.find("п")
>>> end = string.find("ь") + 1
>>> print("Индекс первой буквы 'о' в подстроке:", string.find("о", start, end))
Индекс первой буквы 'о' в подстроке: 7

Проверка есть ли символ в строке

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


>>> string = "Добро пожаловать!"
>>> print("Есть буква 'г'?", string.find("г") != -1)
Есть буква 'г'? False
>>> print("Есть буква 'т'?", string.find("т") != -1)
Есть буква 'т'? True

Поиск последнего вхождения символа в строку

Функция rfind() напоминает find(), а единое отличие в том, что она возвращает максимальный индекс. В обоих случаях же вернется -1, если подстрока не была найдена.

В следующем примере есть строка «Добро пожаловать!». Попробуем найти в ней символ «о» с помощью методов find() и rfind().


>>> string = "Добро пожаловать"
>>> print("Поиск 'о' методом find:", string.find("о"))
Поиск 'о' методом find: 1
>>> print("Поиск 'о' методом rfind:", string.rfind("о"))
Поиск 'о' методом rfind: 11

Вывод показывает, что find() возвращает индекс первого совпадения подстроки, а rfind() — последнего совпадения.

Второй способ поиска — index()

Метод index() помогает найти положение данной подстроки по аналогии с find(). Единственное отличие в том, что index() бросит исключение в том случае, если подстрока не будет найдена, а find() просто вернет -1.

Вот рабочий пример, показывающий разницу в поведении index() и find():


>>> string = "Добро пожаловать"
>>> print("Поиск 'о' методом find:", string.find("о"))
Поиск 'о' методом find: 1
>>> print("Поиск 'о' методом index:", string.index("о"))
Поиск 'о' методом index: 1

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


>>> string = "Добро пожаловать"
>>> print("Поиск 'г' методом find:", string.find("г"))
Поиск 'г' методом find: 1
>>> print("Поиск 'г' методом index:", string.index("г"))
Traceback (most recent call last):
File "pyshell#21", line 1, in module
print("Поиск 'г' методом index:", string.index("г"))
ValueError: substring not found

В этом примере мы пытались найти подстроку «г». Ее там нет, поэтому find() возвращает -1, а index() бросает исключение.

Поиск всех вхождений символа в строку

Чтобы найти общее количество совпадений подстроки в строке можно использовать ту же функцию find(). Пройдемся циклом while по строке и будем задействовать параметр start из метода find().

Изначально переменная start будет равна -1, что бы прибавлять 1 у каждому новому поиску и начать с 0. Внутри цикла проверяем, присутствует ли подстрока в строке с помощью метода find.

Если вернувшееся значение не равно -1, то обновляем значением count.

Вот рабочий пример:


my_string = "Добро пожаловать"
start = -1
count = 0

while True:
start = my_string.find("о", start+1)
if start == -1:
break
count += 1

print("Количество вхождений символа в строку: ", count )

Количество вхождений символа в строку:  4

Выводы

  • Метод find() помогает найти индекс первого совпадения подстроки в данной строке. Возвращает -1, если подстрока не была найдена.
  • В метод передаются три параметра: подстрока, которую нужно найти, start со значением по умолчанию равным 0 и end со значением по умолчанию равным длине строки.
  • Можно искать подстроку в данной строке, задав начальное положение, с которого следует начинать поиск.
  • С помощью параметров start и end можно ограничить зону поиска, чтобы не выполнять его по всей строке.
  • Функция rfind() повторяет возможности find(), но возвращает максимальный индекс (то есть, место последнего совпадения). В обоих случаях возвращается -1, если подстрока не была найдена.
  • index() — еще одна функция, которая возвращает положение подстроки. Отличие лишь в том, что index() бросает исключение, если подстрока не была найдена, а find() возвращает -1.
  • find() можно использовать в том числе и для поиска общего числа совпадений подстроки.
Михаил Кростелев

@twistfire92

Python backend developer

s='aaaaaabaaaaabaaaabaaaab'
pos = s.find('b',s.find('b')+1)

В переменную pos будет записано второе вхождение символа ‘b’

По сути, вторым параметром в методе find() указываешь позицию, следующую после первого вхождения нужного символа

Ответ написан

более трёх лет назад


Комментировать


Комментировать

Python find() – How to Search for a Substring in a String

When you’re working with a Python program, you might need to search for and locate a specific string inside another string.

This is where Python’s built-in string methods come in handy.

In this article, you will learn how to use Python’s built-in find() string method to help you search for a substring inside a string.

Here is what we will cover:

  1. Syntax of the find() method
    1. How to use find() with no start and end parameters example
    2. How to use find() with start and end parameters example
    3. Substring not found example
    4. Is the find() method case-sensitive?
  2. find() vs in keyword
  3. find() vs index()

The find() Method — A Syntax Overview

The find() string method is built into Python’s standard library.

It takes a substring as input and finds its index — that is, the position of the substring inside the string you call the method on.

The general syntax for the find() method looks something like this:

string_object.find("substring", start_index_number, end_index_number)

Let’s break it down:

  • string_object is the original string you are working with and the string you will call the find() method on. This could be any word you want to search through.
  • The find() method takes three parameters – one required and two optional.
  • "substring" is the first required parameter. This is the substring you are trying to find inside string_object. Make sure to include quotation marks.
  • start_index_number is the second parameter and it’s optional. It specifies the starting index and the position from which the search will start. The default value is 0.
  • end_index_number is the third parameter and it’s also optional. It specifies the end index and where the search will stop. The default is the length of the string.
  • Both the start_index_number and the end_index_number specify the range over which the search will take place and they narrow the search down to a particular section.

The return value of the find() method is an integer value.

If the substring is present in the string, find() returns the index, or the character position, of the first occurrence of the specified substring from that given string.

If the substring you are searching for is not present in the string, then find() will return -1. It will not throw an exception.

How to Use find() with No Start and End Parameters Example

The following examples illustrate how to use the find() method using the only required parameter – the substring you want to search.

You can take a single word and search to find the index number of a specific letter:

fave_phrase = "Hello world!"

# find the index of the letter 'w'
search_fave_phrase = fave_phrase.find("w")

print(search_fave_phrase)

#output

# 6

I created a variable named fave_phrase and stored the string Hello world!.

I called the find() method on the variable containing the string and searched for the letter ‘w’ inside Hello world!.

I stored the result of the operation in a variable named search_fave_phrase and then printed its contents to the console.

The return value was the index of w which in this case was the integer 6.

Keep in mind that indexing in programming and Computer Science in general always starts at 0 and not 1.

How to Use find() with Start and End Parameters Example

Using the start and end parameters with the find() method lets you limit your search.

For example, if you wanted to find the index of the letter ‘w’ and start the search from position 3 and not earlier, you would do the following:

fave_phrase = "Hello world!"

# find the index of the letter 'w' starting from position 3
search_fave_phrase = fave_phrase.find("w",3)

print(search_fave_phrase)

#output

# 6

Since the search starts at position 3, the return value will be the first instance of the string containing ‘w’ from that position and onwards.

You can also narrow down the search even more and be more specific with your search with the end parameter:

fave_phrase = "Hello world!"

# find the index of the letter 'w' between the positions 3 and 8
search_fave_phrase = fave_phrase.find("w",3,8)

print(search_fave_phrase)

#output

# 6

Substring Not Found Example

As mentioned earlier, if the substring you specify with find() is not present in the string, then the output will be -1 and not an exception.

fave_phrase = "Hello world!"

# search for the index of the letter 'a' in "Hello world"
search_fave_phrase = fave_phrase.find("a")

print(search_fave_phrase)

# -1

Is the find() Method Case-Sensitive?

What happens if you search for a letter in a different case?

fave_phrase = "Hello world!"

#search for the index of the letter 'W' capitalized
search_fave_phrase = fave_phrase.find("W")

print(search_fave_phrase)

#output

# -1

In an earlier example, I searched for the index of the letter w in the phrase «Hello world!» and the find() method returned its position.

In this case, searching for the letter W capitalized returns -1 – meaning the letter is not present in the string.

So, when searching for a substring with the find() method, remember that the search will be case-sensitive.

The find() Method vs the in Keyword – What’s the Difference?

Use the in keyword to check if the substring is present in the string in the first place.

The general syntax for the in keyword is the following:

substring in string

The in keyword returns a Boolean value – a value that is either True or False.

>>> "w" in "Hello world!"
True

The in operator returns True when the substring is present in the string.

And if the substring is not present, it returns False:

>>> "a" in "Hello world!"
False

Using the in keyword is a helpful first step before using the find() method.

You first check to see if a string contains a substring, and then you can use find() to find the position of the substring. That way, you know for sure that the substring is present.

So, use find() to find the index position of a substring inside a string and not to look if the substring is present in the string.

The find() Method vs the index() Method – What’s the Difference?

Similar to the find() method, the index() method is a string method used for finding the index of a substring inside a string.

So, both methods work in the same way.

The difference between the two methods is that the index() method raises an exception when the substring is not present in the string, in contrast to the find() method that returns the -1 value.

fave_phrase = "Hello world!"

# search for the index of the letter 'a' in 'Hello world!'
search_fave_phrase = fave_phrase.index("a")

print(search_fave_phrase)

#output

# Traceback (most recent call last):
#  File "/Users/dionysialemonaki/python_article/demopython.py", line 4, in <module>
#    search_fave_phrase = fave_phrase.index("a")
# ValueError: substring not found

The example above shows that index() throws a ValueError when the substring is not present.

You may want to use find() over index() when you don’t want to deal with catching and handling any exceptions in your programs.

Conclusion

And there you have it! You now know how to search for a substring in a string using the find() method.

I hope you found this tutorial helpful.

To learn more about the Python programming language, check out freeCodeCamp’s Python certification.

You’ll start from the basics and learn in an interactive and beginner-friendly way. You’ll also build five projects at the end to put into practice and help reinforce your understanding of the concepts you learned.

Thank you for reading, and happy coding!

Happy coding!



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

1. Строки

Строка считывается со стандартного ввода функцией input(). Напомним,
что для двух строк определена операция сложения (конкатенации), также определена
операция умножения строки на число.

Строка состоит из последовательности символов. Узнать количество символов (длину строки)
можно при помощи функции len.

Любой другой объект в Питоне можно перевести к строке, которая ему соответствует.
Для этого нужно вызвать функцию str(), передав ей в качестве параметра объект,
переводимый в строку.

На самом деле каждая строка, с точки зрения Питона, — это объект
класса str. Чтобы получить по объекту другой объект другого класса, как-то ему соответствующий,
можно использовать функцию приведения. Имя этой функции совпадает с именем класса, к которому мы приводим объект.
(Для знатоков: эта функция — это конструктор объектов данного класса.) Пример: int — класс
для целых чисел. Перевод строки в число осуществляется функцией int().

s = input()
print(len(s))
t = input()
number = int(t)
u = str(number)
print(s * 3)
print(s + ' ' + u)

2. Срезы (slices)

Срез (slice) — извлечение из данной строки одного символа или некоторого фрагмента
подстроки или подпоследовательности.

Есть три формы срезов. Самая простая форма среза: взятие одного символа
строки, а именно, S[i] — это срез, состоящий из одного символа,
который имеет номер i. При этом считается, что нумерация начинается
с числа 0. То есть если S = 'Hello', то
S[0] == 'H', S[1] == 'e', S[2] == 'l',
S[3] == 'l', S[4] == 'o'.

Заметим, что в Питоне нет отдельного типа для символов строки. Каждый объект, который получается
в результате среза S[i] — это тоже строка типа str.

Номера символов в строке (а также в других структурах данных: списках, кортежах)
называются индексом.

Если указать отрицательное значение индекса, то номер будет отсчитываться
с конца, начиная с номера -1. То есть S[-1] == 'o',
S[-2] == 'l', S[-3] == 'l', S[-4] == 'e',
S[-5] == 'H'.

Или в виде таблицы:

Строка S H e l l o
Индекс S[0] S[1] S[2] S[3] S[4]
Индекс S[-5] S[-4] S[-3] S[-2] S[-1]

Если же номер символа в срезе строки S больше либо равен len(S),
или меньше, чем -len(S), то при обращении к этому символу строки произойдет
ошибка IndexError: string index out of range.

Срез с двумя параметрами: S[a:b]
возвращает подстроку из b - a символов,
начиная с символа c индексом a,
то есть до символа с индексом b, не включая его.
Например, S[1:4] == 'ell', то же самое получится
если написать S[-4:-1]. Можно использовать как положительные,
так и отрицательные индексы в одном срезе, например, S[1:-1] —
это строка без первого и последнего символа (срез начинается с символа с индексом 1 и
заканчиватеся индексом -1, не включая его).

При использовании такой формы среза ошибки IndexError
никогда не возникает. Например, срез S[1:5]
вернет строку 'ello', таким же будет результат,
если сделать второй индекс очень большим, например,
S[1:100] (если в строке не более 100 символов).

Если опустить второй параметр (но поставить двоеточие),
то срез берется до конца строки. Например, чтобы удалить
из строки первый символ (его индекс равен 0), можно
взять срез S[1:]. Аналогично
если опустить первый параметр, то можно взять срез от начала строки.
То есть удалить из строки последний символ можно при помощи среза
S[:-1]. Срез S[:] совпадает с самой строкой
S.

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

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

Если задать срез с тремя параметрами S[a:b:d],
то третий параметр задает шаг, как в случае с функцией
range, то есть будут взяты символы с индексами
a, a + d, a + 2 * d и т. д.
При задании значения третьего параметра, равному 2, в срез попадет
кажый второй символ, а если взять значение среза, равное
-1, то символы будут идти в обратном порядке.
Например, можно перевернуть строку срезом S[::-1].

s = 'abcdefg'
print(s[1])
print(s[-1])
print(s[1:3])
print(s[1:-1])
print(s[:3])
print(s[2:])
print(s[:-1])
print(s[::2])
print(s[1::2])
print(s[::-1])

Обратите внимание на то, как похож третий параметр среза на третий параметр функции range():

s = 'abcdefghijklm'
print(s[0:10:2])
for i in range(0, 10, 2):
    print(i, s[i])

3. Методы

Метод — это функция, применяемая к объекту, в данном случае — к строке.
Метод вызывается в виде Имя_объекта.Имя_метода(параметры).
Например, S.find("e") — это применение к строке S
метода find с одним параметром "e".

3.1. Методы find и rfind

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

S = 'Hello'
print(S.find('e'))
# вернёт 1
print(S.find('ll'))
# вернёт 2
print(S.find('L'))
# вернёт -1

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

S = 'Hello'
print(S.find('l'))
# вернёт 2
print(S.rfind('l'))
# вернёт 3

Если вызвать метод find с тремя параметрами
S.find(T, a, b), то поиск будет осуществляться
в срезе S[a:b]. Если указать только два параметра
S.find(T, a), то поиск будет осуществляться
в срезе S[a:], то есть начиная с символа с индексом
a и до конца строки. Метод S.find(T, a, b)
возращает индекс в строке S, а не индекс относительно среза.

3.2. Метод replace

Метод replace заменяет все вхождения одной строки на другую. Формат:
S.replace(old, new) — заменить в строке S
все вхождения подстроки old на подстроку new. Пример:

print('Hello'.replace('l', 'L'))
# вернёт 'HeLLo'

Если методу replace задать еще один параметр: S.replace(old, new, count),
то заменены будут не все вхождения, а только не больше, чем первые count из них.

print('Abrakadabra'.replace('a', 'A', 2))
# вернёт 'AbrAkAdabra'

3.3. Метод count

Подсчитывает количество вхождений одной строки в другую строку. Простейшая
форма вызова S.count(T)  возвращает число вхождений строки
T внутри строки S. При этом подсчитываются только
непересекающиеся вхождения, например:

print('Abracadabra'.count('a'))
# вернёт 4
print(('a' * 10).count('aa'))
# вернёт 5

При указании трех параметров S.count(T, a, b),
будет выполнен подсчет числа вхождений строки T
в срезе S[a:b].



Ссылки на задачи доступны в меню слева. Эталонные решения теперь доступны на странице самой задачи.

7.1. Составной тип данных¶

К этому момент мы уже встречали пять типов данных: int, float, bool, NoneType и str. Тип str — строка — качественно отличается от четырех других тем, что состоит из меньших элементов — символов.

Типы, включающие меньшие элементы, называются составными типами данных. В разных ситуациях можно либо обращаться с составным типом данных как с чем-то цельным, либо работать с его отдельными частями. Эта двоякость полезна.

Оператор [] выбирает единственный символ из строки:

>>> fruit = "banana"
>>> letter = fruit[1]
>>> print letter

Выражение fruit[1] выбирает символ номер 1 из строки fruit. Результат присваивается переменной letter. Отобразив letter, вы, вероятно, удивитесь:

Ведь первая буква в строке «banana» не a! Но программисты часто ведут счет, начиная с 0. Буква номер 0 в строке «banana» — буква b. Буква номер 1 — a, номер 2 — n, и так далее.

Если вам нужна буква номер 0, просто поместите 0, или любое выражение, дающее 0, в квадратные скобки:

>>> letter = fruit[0]
>>> print letter
b

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

7.2. Длина¶

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

>>> fruit = "banana"
>>> len(fruit)
6

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

length = len(fruit)
last = fruit[length]       # Ошибка!

Это не работает! Вы получите ошибку выполнения IndexError: string index out of range. Причина в том, что в строке «banana» нет символа с индексом 6. Так как мы начинаем счет с 0, шесть символов пронумерованы от 0 до 5. Для того, чтобы получить последний символ, нужно из length вычесть 1:

length = len(fruit)
last = fruit[length-1]

Кроме того, можно использовать отрицательные индексы, которые позволяют вести счет от конца строки. Выражение fruit[-1] дает последний символ строки, fruit[-2] дает второй символ от конца строки, и так далее.

7.3. Обход и цикл for

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

index = 0
while index < len(fruit):
    letter = fruit[index]
    print letter
    index += 1

Этот цикл обходит строку и выводит каждую букву в отдельной строке. Условие цикла здесь index < len(fruit), так что, когда index становится равным длине строки, условие становится ложным и тело цикла больше не выполняется. Последний обработанный символ имеет индекс len(fruit)-1, и является последним символом в строке.

Обход элементов последовательности настолько часто используется, что Python предлагает для этого другой, более простой синтаксис — цикл for:

for char in fruit:
    print char

В каждой итерации переменной char присваивается очередной символ строки. Цикл продолжается до тех пор, пока строка не закончится.

Следующий пример показывает, как с помощью конкатенации и цикла for сгенерировать последовательность в алфавитном порядке. Например, Роберт МакКлоски в своей книге дал такие имена утятам: Jack, Kack, Lack, Mack, Nack, Ouack, Pack и Quack. Следующий цикл выводит имена утят в алфавитном порядке:

prefixes = "JKLMNOPQ"
suffix = "ack"

for letter in prefixes:
    print letter + suffix

Эта программа выводит:

Jack
Kack
Lack
Mack
Nack
Oack
Pack
Qack

Конечно, это не совсем то, что нужно, поскольку Ouack и Quack написаны неправильно. Вам предстоит исправить это в одном из упражнений к этой главе.

7.4. Срезы строк¶

Подстроку строки будем называть срезом. Получение среза строки похоже на получение одного символа:

>>> s = "Peter, Paul, and Mary"
>>> print s[0:5]
Peter
>>> print s[7:11]
Paul
>>> print s[17:21]
Mary

Оператор [n:m] возвращает часть строки, начиная с символа с индексом n по символ с индексом m, включая первый, но исключая последний. Это поведение может показаться странным на первый взгляд; но представьте, что индексы указывают на места между символами, как на следующей диаграмме:

Строка 'banana'

Если в операторе среза опустить первый индекс (перед двоеточием), то началом среза будет начало строки (индекс 0). Если опустить второй индекс, то срез включит все символы до конца строки. Таким образом:

>>> fruit = "banana"
>>> fruit[:3]
'ban'
>>> fruit[3:]
'ana'

А как вы думаете, что дает срез s[:]?

7.5. Сравнение строк¶

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

if word == "banana":
    print "Yes, we have no bananas!"

С помощью других операторов сравнения можно располагать слова в алфавитном порядке:

if word < "banana":
    print "Your word, " + word + ", comes before banana."
elif word > "banana":
    print "Your word, " + word + ", comes after banana."
else:
    print "Yes, we have no bananas!"

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

Your word, Zebra, comes before banana.

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

7.6. Строки неизменяемы¶

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

greeting = "Hello, world!"
greeting[0] = 'J'            # Ошибка!
print greeting

Вместо вывода Jello, world! этот код выдаст сообщение об ошибке выполнения TypeError: ‘str’ object doesn’t support item assignment.

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

greeting = "Hello, world!"
newGreeting = 'J' + greeting[1:]
print newGreeting

Здесь конкатенируются первая буква и срез строки greeting. Это никак не влияет на первоначальную строку.

7.7. Оператор in

Оператор in проверяет, является ли одна строка частью другой строки (ее подстрокой):

>>> 'p' in 'apple'
True
>>> 'i' in 'apple'
False
>>> 'ap' in 'apple'
True
>>> 'pa' in 'apple'
False

Заметьте, что строка является подстрокой самой себя:

>>> 'a' in 'a'
True
>>> 'apple' in 'apple'
True

Комбинируя оператор in с конкатенацией строк, напишем функцию, удаляющую из строки все гласные:

def remove_vowels(s):
    vowels = "aeiouAEIOU"
    s_without_vowels = ""
    for letter in s:
        if letter not in vowels:
            s_without_vowels += letter
    return s_without_vowels

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

7.8. Функция find

Что делает следующая функция?

def find(strng, ch):
    index = 0
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1

В некотором смысле, find является противоположностью оператора []. Вместо того, чтобы по индексу извлекать символ, эта функция по символу находит индекс, под которым этот символ присутствует в строке. Если символ не найден, функция возвращает -1.

Это первый случай, когда мы видим предложение return в теле цикла. Если strng[index] == ch, функция немедленно возвращает значение и завершается, прекращая выполнение цикла.

Если искомого символа в строке нет, то цикл завершится, как обычно, после чего программа завершится, возвращая -1.

Этот прием иногда называют эврика-обходом. Ведь как только мы нашли то, что ищем, мы можем закричать “Эврика!”, и больше не искать.

7.9. Счетчик в цикле¶

Следующая программа подсчитывает, сколько раз в строке встречается буква a. Это еще один пример использования приема счетчик, с которым мы познакомились в главе 6:

fruit = "banana"
count = 0
for char in fruit:
    if char == 'a':
        count += 1
print count

7.10. Необязательные параметры¶

Для того, чтобы найти в строке второе или третье вхождение некоторого символа, можно изменить функцию find, добавив третий параметр для указания позиции начала поиска:

def find2(strng, ch, start):
    index = start
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1

Вызов find2(‘banana’, ‘a’, 2) теперь возвращает 3, позицию первого вхождения ‘a’ в строке ‘banana’ после позиции 2. А что вернет вызов find2(‘banana’, ‘n’, 3)? Если вы ответили 4, значит, вы поняли, как работает find2.

Но можно пойти дальше, и объединить find и find2 с помощью необязательного параметра:

def find(strng, ch, start=0):
    index = start
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1

Вызов find(‘banana’, ‘a’, 2) теперь ведет себя так же, как find2, и, в то же время, при вызове find(‘banana’, ‘a’) параметр start получит значение по умолчанию 0.

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

def find(strng, ch, start=0, step=1):
    index = start
    while 0 <= index < len(strng):
        if strng[index] == ch:
            return index
        index += step
    return -1

Передав значение -1 для step, мы заставим функцию искать от конца к началу. Обратите внимание, что в условии цикла теперь нужно поверять достижение index как нижней, так и верхней границы строки.

7.11. Модуль string

Модуль string содержит полезные функции для работы со строками. Как обычно, для того, чтобы использовать модуль, мы должны его импортировать:

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

Вы получите список элементов модуля string:

[‘Template’, ‘_TemplateMetaclass’, ‘__builtins__’, ‘__doc__’,
‘__file__’, ‘__name__’, ‘_float’, ‘_idmap’, ‘_idmapL’, ‘_int’,
‘_long’, ‘_multimap’, ‘_re’, ‘ascii_letters’, ‘ascii_lowercase’,
‘ascii_uppercase’, ‘atof’, ‘atof_error’, ‘atoi’, ‘atoi_error’, ‘atol’,
‘atol_error’, ‘capitalize’, ‘capwords’, ‘center’, ‘count’, ‘digits’,
‘expandtabs’, ‘find’, ‘hexdigits’, ‘index’, ‘index_error’, ‘join’,
‘joinfields’, ‘letters’, ‘ljust’, ‘lower’, ‘lowercase’, ‘lstrip’,
‘maketrans’, ‘octdigits’, ‘printable’, ‘punctuation’, ‘replace’,
‘rfind’, ‘rindex’, ‘rjust’, ‘rsplit’, ‘rstrip’, ‘split’,
‘splitfields’, ‘strip’, ‘swapcase’, ‘translate’, ‘upper’, ‘uppercase’,
‘whitespace’, ‘zfill’]

Чтобы побольше узнать о любом из элементов списка, можно воспользоваться функцией type. Укажите имя модуля и имя элемента, используя точечную нотацию.

>>> type(string.digits)
<type 'str'>
>>> type(string.find)
<type 'function'>

Поскольку string.digits (англ.: цифры) является строкой, мы можем вывести ее и посмотреть, что она содержит:

>>> print string.digits
0123456789

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

Функция string.find делает, в основном, то же самое, что и функция, которую мы написали. Чтобы узнать о ней больше, мы можем вывести ее документирующую строку __doc__, которая содержит документацию по этой функции:

>>> print string.find.__doc__
find(s, sub [,start [,end]]) -> in

    Return the lowest index in s where substring sub is found,
    such that sub is contained within s[start,end].  Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.

Параметры, указанные в документации в квадратных скобках, являются необязательными. Заметьте, что функцию string.find можно использовать почти так же, как нашу собственную find:

>>> fruit = "banana"
>>> index = string.find(fruit, "a")
>>> print index
1

Этот пример демонстрирует одно из преимуществ модулей: они помогают избежать конфликта между именами встроенных функций и функций, определенных пользователем. Используя точечную нотацию, мы можем указать, какая именно функция find нам нужна.

На самом деле, string.find является функцией более общего применения, чем наша. Она может искать подстроки, а не только отдельные символы:

>>> string.find("banana", "na")
2

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

>>> string.find("banana", "na", 3)
4

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

>>> string.find("bob", "b", 1, 2)
-1

В этом примере поиск не удался, поскольку буква b не встречается между индексами 1 и 2 (последний исключается).

7.12. Классификация символов¶

Часто бывает нужно исследовать символ и выяснить, например, к какому регистру он принадлежит, является он буквой или цифрой. Модуль string предоставляет несколько констант, которые полезны для этих целей. С одной из них, string.digits, мы уже встречались.

Строка string.lowercase содержит все латинские символы, которые система относит к нижнему регистру. Аналогично, string.uppercase содержит все латинские символы верхнего регистра. Выполните следующее и посмотрите, что вы получите:

print string.lowercase
print string.uppercase
print string.digits

С помощью этих констант и функции find можно классифицировать символы. Например, если find(lowercase, ch) возвращает число, отличное от -1, значит, ch является символом нижнего регистра:

def is_lower(ch):
    return string.find(string.lowercase, ch) != -1

Как вариант, можно воспользоваться оператором in:

def is_lower(ch):
    return ch in string.lowercase

Той же цели можно достичь с помощью операторов сравнения:

def is_lower(ch):
    return 'a' <= ch <= 'z'

Если ch больше или равен a и меньше или равен z, то он является символом нижнего регистра.

Еще одна константа, определенная в модуле string, может удивить вас, если вывести ее на экран:

>>> print string.whitespace

Пробельные символы перемещают курсор, ничего не отображая. Они создают пустое пространство между видимыми символами. Константа string.whitespace содержит все пробельные символы, включая пробел, табуляцию (t) и перевод строки (n).

В модуле string содержится много других полезных функций. Но эта книга — не справочник. Если вам нужно больше узнать о возможностях модулей Python, обратитесь к справочнику Python Library Reference. Так же, как и другая документация, справочник по библиотеке Python доступен на сайте Python http://www.python.org.

7.13. Форматирование строк¶

Наиболее выразительный и мощный способ форматирования строк в Python — использование оператора форматирования строки % вместе с операндами для форматирования. Чтобы посмотреть, как это работает, начнем с нескольких примеров:

>>> "His name is %s."  % "Arthur"
'His name is Arthur.'
>>> name = "Alice"
>>> age = 10
>>> "I am %s and I am %d years old." % (name, age)
'I am Alice and I am 10 years old.'
>>> n1 = 4
>>> n2 = 5
>>> "2**10 = %d and %d * %d = %f" % (2**10, n1, n2, n1 * n2)
'2**10 = 1024 and 4 * 5 = 20.000000'
>>>

Операция форматирования строки записывается так:

"<формат>" % (<значения>)

Левый операнд формат — строка, содержащая, помимо прочего, спецификации преобразования, которые начинаются с символа %. Справа от оператора форматирования % записывается в скобках последовательность значений, разделенных запятыми. Каждое значение в этой последовательности соответствует спецификации преобразования в форматируемой строке слева от оператора %. Скобки необязательны, если последовательность включает только одно значение.

В первом из приведенных выше примеров только одна спецификация преобразования, %s, обозначающая строку. Ей соответствует единственное значение «Arthur», не заключенное в скобки.

Во втором примере имеются переменные name со строковым значением «Alice» и age с целочисленным значением 10. Они соответствуют двум спецификациям преобразования, %s и %d. Во второй спецификации d обозначает десятичное целое число.

В третьем примере переменные n1 и n2 имеют целочисленные значения 4 и 5, соответственно. В форматируемой строке имеются четыре спецификации преобразования: три %d и одна %f. Спецификация преобразования %f показывает, что соответствующее значение должно быть представлено как число с плавающей точкой. Четыре значения, соответствующие четырем спецификациям преобразования, следующие: 2**10, n1, n2, and n1 * n2.

В этой книге нам будет достаточно форматных преобразований s, d и f. Полный их список можно найти в справочнике по библиотеке Python в разделе String Formatting Operations.

Следующий пример демонстрирует реальную пользу от форматирования строк:

i = 1
print "iti**2ti**3ti**5ti**10ti**20"
while i <= 10:
    print i, 't', i**2, 't', i**3, 't', i**5, 't', i**10, 't', i**20
    i += 1

Программа печатает таблицу степеней чисел от 1 до 10. В этом варианте программы для выравнивания столбцов значений используется символ табуляции (t). Это перестает работать, как только число в столбце становится достаточно длинным и достигает следующей позиции табуляции:

i       i**2    i**3    i**5    i**10   i**20
1       1       1       1       1       1
2       4       8       32      1024    1048576
3       9       27      243     59049   3486784401
4       16      64      1024    1048576         1099511627776
5       25      125     3125    9765625         95367431640625
6       36      216     7776    60466176        3656158440062976
7       49      343     16807   282475249       79792266297612001
8       64      512     32768   1073741824      1152921504606846976
9       81      729     59049   3486784401      12157665459056928801
10      100     1000    100000  10000000000     100000000000000000000

Также обратите внимание на то, что первый столбец получается намного шире, чем требуется. Лучшим решением в данном случае было бы независимо устанавливать ширину каждого столбца. Форматирование строк предоставляет такую возможность:

i = 1
print "%-4s%-5s%-6s%-8s%-13s%-15s" % 
      ('i', 'i**2', 'i**3', 'i**5', 'i**10', 'i**20')
while i <= 10:
    print "%-4d%-5d%-6d%-8d%-13d%-15d" % (i, i**2, i**3, i**5, i**10, i**20)
    i += 1

Эта версия программы выводит следующее:

i   i**2 i**3  i**5    i**10        i**20
1   1    1     1       1            1
2   4    8     32      1024         1048576
3   9    27    243     59049        3486784401
4   16   64    1024    1048576      1099511627776
5   25   125   3125    9765625      95367431640625
6   36   216   7776    60466176     3656158440062976
7   49   343   16807   282475249    79792266297612001
8   64   512   32768   1073741824   1152921504606846976
9   81   729   59049   3486784401   12157665459056928801
10  100  1000  100000  10000000000  100000000000000000000

Знак после % в спецификации преобразования обозначает выравнивание по левому краю, а число обозначает минимальную длину. Так, %-13d обозначает десятичное число длиной не менее 13 символов, выровненное по левому краю.

7.14. Глоссарий¶

документирующая строка
Строковое значение, расположенное сразу после заголовка функции или
модуля (и, как мы увидим дальше, после заголовка класса или метода).
Документирующие строки, или докстроки, предоставляют удобный способ
документировать код. Докстроки также используются модулем doctest
для автоматического тестирования.
значение по умолчанию
Значение, которое получит необязательный параметр, если при вызове
функции для него не передан аргумент.
индекс
Переменная или значение, используемое для доступа к элементу некоторого
упорядоченного набора, например, к символу в строке.
неизменяемый тип данных
Неизменяемым является составной тип данных, элементам которого нельзя
присвоить новые значения.
необязательный параметр
Параметр, для которого вы заголовке функции указано значение по умолчанию.
Параметр получит значение по умолчанию, если при вызове функции не будет
передан аргумент для него.
обход
Перебор всех элементов некоторого множества, с выполнением над каждым
некоторой операции.
пробельные символы
Символы, которые перемещают курсор, не выводя видимые символы. Строка
string.whitespace содержит все пробельные символы.
составной тип данных:
Тип данных, включающий компоненты, которые сами относятся к некоторому
типу данных и могут использоваться как самостоятельные значения.
срез
Часть строки (подстрока), заданная диапазоном индексов. Вообще, в Python
можно получить подпоследовательность любой последовательности (не только
строки) с помощью оператора среза последовательность[start:stop].
точечная нотация
Использование оператора . (точка), например, для доступа к
функции внутри модуля.

7.15. Упражнения¶

  1. Измените следующий код:

    prefixes = "JKLMNOPQ"
    suffix = "ack"
    
    for letter in prefixes:
        print letter + suffix
    

    так, чтобы Ouack и Quack выводились корректно.

  2. Оформите следующий код как функцию с именем count_letters:

    fruit = "banana"
    count = 0
    for char in fruit:
        if char == 'a':
            count += 1
    print count
    

    Обобщите эту функцию, чтобы она принимала
    строку и символ в качестве аргументов.

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

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

  5. Создайте файл с именем stringtools.py и поместите в него следующее:

    def reverse(s):
        """
          >>> reverse('happy')
          'yppah'
          >>> reverse('Python')
          'nohtyP'
          >>> reverse("")
          ''
          >>> reverse("P")
          'P'
        """
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    

    Напишите тело функции reverse (англ.: перевернуть) так, чтобы доктесты
    успешно прошли.

  6. Напишите функцию mirror (англ.: зеркало, отражать) в файле stringtools.py.

    def mirror(s):
        """
          >>> mirror("good")
          'gooddoog'
          >>> mirror("yes")
          'yessey'
          >>> mirror('Python')
          'PythonnohtyP'
          >>> mirror("")
          ''
          >>> mirror("a")
          'aa'
        """
    

    Напишите тело функции так, чтобы доктесты успешно прошли.

  7. Добавьте функцию remove_letter (англ.: удалить букву) в файл stringtools.py .

    def remove_letter(letter, strng):
        """
          >>> remove_letter('a', 'apple')
          'pple'
          >>> remove_letter('a', 'banana')
          'bnn'
          >>> remove_letter('z', 'banana')
          'banana'
          >>> remove_letter('i', 'Mississippi')
          'Msssspp'
        """
    

    Напишите тело функции так, чтобы доктесты успешно прошли.

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

    def is_palindrome(s):
        """
          >>> is_palindrome('abba')
          True
          >>> is_palindrome('abab')
          False
          >>> is_palindrome('tenet')
          True
          >>> is_palindrome('banana')
          False
          >>> is_palindrome('straw warts')
          True
        """
    
    def count(sub, s):
        """
          >>> count('is', 'Mississippi')
          2
          >>> count('an', 'banana')
          2
          >>> count('ana', 'banana')
          2
          >>> count('nana', 'banana')
          1
          >>> count('nanan', 'banana')
          0
        """
    
    def remove(sub, s):
        """
          >>> remove('an', 'banana')
          'bana'
          >>> remove('cyc', 'bicycle')
          'bile'
          >>> remove('iss', 'Mississippi')
          'Missippi'
          >>> remove('egg', 'bicycle')
          'bicycle'
        """
    
    def remove_all(sub, s):
        """
          >>> remove_all('an', 'banana')
          'ba'
          >>> remove_all('cyc', 'bicycle')
          'bile'
          >>> remove_all('iss', 'Mississippi')
          'Mippi'
          >>> remove_all('eggs', 'bicycle')
          'bicycle'
        """
    
  9. Попробуйте выполнить каждую из следующих операций форматирования строки в
    интерактивном режиме Python и объясните результаты:

    1. «%s %d %f» % (5, 5, 5)
    2. «%-.2f» % 3
    3. «%-10.2f%-10.2f» % (7, 1.0/2)
    4. print « $%5.2fn $%5.2fn $%5.2f» % (3, 4.5, 11.2)
  10. Форматируемые строки в следующих операциях содержат ошибки. Исправьте их:

    1. «%s %s %s %s» % (‘this’, ‘that’, ‘something’)
    2. «%s %s %s» % (‘yes’, ‘no’, ‘up’, ‘down’)
    3. «%d %f %f» % (3, 3, ‘three’)

Понравилась статья? Поделить с друзьями:
  • Как найти книгу если ты ее потерял
  • Как найти код регистрации на мос ру
  • Как найти размер медианы треугольника
  • Как найти высокооплачиваемую работу для души
  • Как составить план работы в сдк