15542
Комментарий:
|
23737
|
Удаления помечены так. | Добавления помечены так. |
Строка 206: | Строка 206: |
>>> a.find("SDF!") # Однако в случае успеха не выбрасывает ошибку, а возвращает -1 | >>> a.find("SDF!") # Однако в случае неуспеха не выбрасывает ошибку, а возвращает -1 |
Строка 212: | Строка 212: |
Названия методов из этой группы начинаются на '''`is`'''. Сами эти методы призваны проверять различные свойтва строк: | Названия методов из этой группы начинаются на '''`is`'''. Сами эти методы призваны проверять различные свойства строк: |
Строка 257: | Строка 257: |
>>> "Avalidtitle".istitle() # istile - очень странный метод, проверяющий, состоит ли строка только из букв и является ли первая из них прописной, а остальные - строчными True >>> "A non-valid title".istitle() |
>>> "Avalidtitle".istitle() # istitle - проверяет, состоит ли строка только из слов, разделённых пробелами, состоящих только из букв и начинающихся с прописной буквы каждое True >>> "A nonvalid title".istitle() |
Строка 269: | Строка 269: |
>>> "A Valid Title".istitle() True |
|
Строка 275: | Строка 277: |
{{{#!highlight pycon >>> s = "qWe" >>> s.lower() # lower - преобразование всех букв в строчные 'qwe' >>> s.upper() # upper - преобразование всех букв в прописные 'QWE' >>> a.capitalize() # capitalize - преобразование первой буквы в прописную 'Asd asdfsdv zxcdfg%^ 567567 gfhfg oikpi' >>> a.title() # title - преобразование первых букв всех слов в прописные 'Asd Asdfsdv Zxcdfg%^ 567567 Gfhfg Oikpi' >>> s.swapcase() # swapcase - сменить регистр всех букв в строке 'QwE' >>> a.casefold() # casefold - привести строку к такому виду, в котором её возможно сравнивать (>, <) с другими строками вне зависимости от регистра букв 'asd asdfsdv zxcdfg%^ 567567 gfhfg oikpi' }}} === replace === Гораздо более интересный метод - '''`replace`'''. Он позволяет заменить вхождения подстроки на заданную строку: {{{#!highlight pycon >>> a 'asd aSDFSDv zxcdfg%^ 567567 GFHFG oikpi' >>> a.replace("SD","----") # По умолчанию заменяются все вхождения 'asd a----F----v zxcdfg%^ 567567 GFHFG oikpi' >>> a.replace("SD","----",1) # Но можно и ограничить количество замен 'asd a----FSDv zxcdfg%^ 567567 GFHFG oikpi' }}} === Работа с пробельными символами === Как убрать лишние пробелы? '''Методами `lstrip`, `rstrip` и `strip`''': {{{#!highlight pycon >>> b = " \t za warudo \t " >>> b.lstrip() 'za warudo \t ' >>> b.rstrip() ' \t za warudo' >>> b.strip() 'za warudo' }}} Кроме того, есть метод '''`expandtabs`''', являющийся наследием второго питона и позволяющий раскрыть символы табуляции в строке по определённым правилам. === zfill === Метод '''`zfill`''' позволяет дополнить строку, состоящую из цифр, нулями слева, чтобы получить строку длины не меньше указанной: {{{#!highlight pycon >>> s = "1" >>> s.zfill(10) '0000000001' >>> s = "-1" >>> s.zfill(10) # Вот и отличие от ljust: zfill интерпретирует строку именно как число (но это работает только с целыми десятичными числами) '-000000001' }}} == split и join == Самые интересные и полезные методы работы со строками я даже выделил в отдельный раздел. === split === '''Метод `split` позволяет разбить строку на части по какому-либо символу (по умолчанию - по целым подпоследовательностям, состоящим из пробельных символов). При этом результатом его работы будет список подстрок исходной строки:''' {{{#!highlight pycon >>> a 'asd aSDFSDv zxcdfg%^ 567567 GFHFG oikpi' >>> a.split() # Разбить строку на подстроки по пробельным символам (последовательность пробельных символов как бы считается за один символ) ['asd', 'aSDFSDv', 'zxcdfg%^', '567567', 'GFHFG', 'oikpi'] >>> nn = "123 32 2134 346 657 56 1234 436" # Это очень удобно для анализа ввода с клавиатуры >>> [int(n) for n in nn.split()] [123, 32, 2134, 346, 657, 56, 1234, 436] >>> nn.split("3") # Можно и указать подстроку, по которой выполнять разбиение ['12', ' ', '2 21', '4 ', '46 657 56 12', '4 4', '6'] >>> a = "a,,d,r,,,e,,r" # Если вы указываете подстроку, по которой разбивать данную, вы можете получить в массиве и пустые строки >>> a.split(",") ['a', '', 'd', 'r', '', '', 'e', '', 'r'] >>> a.split(",,") # Эта подстрока, конечно, не обязана состоять из одного символа ['a', 'd,r', ',e', 'r'] }}} '''Метод `split` очень, ОЧЕНЬ часто используется при анализе входных данных с клавиатуры.''' Частный случай работы метода `split`, с некоторыми нюансами (например, независимость от используемого в ос символа новой строки), представляет метод '''`splitlines`''': {{{#!highlight pycon >>> s = "This is a long\n text with\n multiple\n line endings\n" >>> s.splitlines() # splitlines позволяет разбить строку по символам переноса строки (какой бы символ для этого ни использовался в ос) ['This is a long', ' text with', ' multiple', ' line endings'] }}} === join === Можно выполнить и обратную операцию - объединить несколько строк в одну: {{{#!highlight pycon >>> sn = nn.split() >>> "__".join(sn) # Таким образом можно задать тот разделитель, которым нужно соединять строки '123__32__2134__346__657__56__1234__436' >>> "".join(sn) # Т.к. join - метод строки, то, даже если нам не нужен разделитель, хотя бы пустую строку указать придётся '123322134346657561234436' }}} '''Может возникнуть вопрос: зачем это делать с помощью отдельного метода, если есть операция конкатенации `+`?''' '''Эффективность. Если только вы хотите объединить не две строки, а больше, попытка сделать это через конкатенацию приведёт к тому, что на каждую конкатенацию двух строк интерпретатор создаст отдельный объект (даже если записать всё выражение в виде "a + b + c + d + ...").''' В CPython эту проблему обходят с помощью хака, но вообще полагаться на эффективную реализацию конкатенации строк не стоит (но и ради сложения двух строк использовать `join` смысла нет). {{{#!wiki red/solid /!\ В интернетах если не продолжаются до сих пор, то, по крайней мере, легко находятся старые холивары на тему того, какой метод эффективнее, и не всегда [[https://stackoverflow.com/questions/12169839/which-is-the-preferred-way-to-concatenate-a-string-in-python | наиболее оцененный комментарий]] - верный. Так что будьте аккуратны, сверяйтесь с несколькими источниками и не забывайте проверять даты публикаций. }}} == Форматирование строк == Пока не заполнено - посмотрите, [[https://uneex.org/LecturesCMC/PythonIntro2018/04_CircleSequence/Conspect#A.2BBCQEPgRABDwEMARCBDgEQAQ.2BBDIEMAQ9BDgENQ_.2BBEEEQgRABD4EOg- | что мы уже знаем]] про форматирование строк. |
1. Лекция 6
26 октября 2018 г.
Заметили ошибку или есть предложение? Напишите на почту: romansdidnotcrucify@gmail.com
ACHTUNG! WORK IN PROGRESS!
Данная страница ещё не закончена и находится в процессе дополнения и переработки. Почитать уже можно, но не забудьте потом заглянуть, когда будет полная версия.
2. Строки
2.1. Задание строк
Строки в питоне - это такие последовательности (смысл их интуитивно понятен - набор символов).
Задавать строки можно четырьмя способами:
с помощью двойных кавычек: "John";
с помощью одинарных кавычек: 'Doe' (никаких отличий от двойных кавычек);
с помощью тройных кавычек: '''John Doe can be multiline''' - позволяют задать многострочную строку (многострочный строковый литерал), а также использовать в её тексте кавычки, не прибегая к специальным символам в исходном коде;
с помощью преобразования объектов других типов: str(12).
Если вы задаёте строку с помощью двойных кавычек - можете спокойно использовать в её тексте одинарные, и наоборот. Если же вы хотите использовать в тексте строки тот же тип кавычек, которым вы обрамляете строку, вам придётся пользоваться одним из инструментов, описанных ниже.
Кстати, обратите внимание на разницу в выводе (функция print, на самом деле, выводит результат метода __str__, a интерпретатор в выводе использует __repr__):
1 >>> a = '''A multiline string
2 ... is a string that takes multiple
3 ... lines of text
4 ... '''
5 >>> a # Интерпретатор при выводе использует результат работы метода объекта __repr__ - он представляет в виде строки внутреннюю структуру объекта
6 'A multiline string\nis a string that takes multiple\nlines of text\n'
7 >>> print(a.__str__()) # __str__ задаёт строковое представление объекта - этот-то метод объекта (если он есть) и использует print
8 A multiline string
9 is a string that takes multiple
10 lines of text
11
12 >>> print(a.__repr__())
13 'A multiline string\nis a string that takes multiple\nlines of text\n'
14
2.2. Спецсимволы (управляющие символы)
При задании строки можно использовать т.н. управляющие символы - последовательности символов, которые будут интерпретироваться особым образом. В питоне такие последовательности начинаются с символа \ (backslash):
\n - перенос строки;
\t - табуляция;
\r - символ возврата каретки (подробнее здесь);
\', \" - символ - одинарная/двойная кавычка (вне зависимости от того, с помощью каких кавычек вы задаёте строковый литерал).
1 >>> print('There will be a\nhuge fall')
2 There wiil be a
3 huge fall
4 >>> print("We need to explore\t\t\touter space")
5 We need to explore outer space
6 >>> print("I don't want to set the world on fire\rI do!!!") # Символ возврата каретки переносит наш "курсор" - то место, в которое происходит вывод - в начало строки
7 I do!!! want to set the world on fire
8 >>> print("Yep, I'm using \"double quotes\" in a double-quoted string literal")
9 Yep, I'm using "double quotes" in a double-quoted string literal
10
Полную таблицу спецсимволов можно посмотреть здесь
2.3. Коды символов
В разговоре об управляющих символах уместно будет упомянуть функции, позволяющие работать напрямую с кодами символов - ord и chr:
1 >>> ord("a") # Получить номер символа в кодировке (ord вернёт десятичное число)
2 97
3 >>> ord("abc") # Обратите внимание, что ord принимает на вход строку именно из одного символа
4 Traceback (most recent call last):
5 File "<stdin>", line 1, in <module>
6 TypeError: ord() expected a character, but string of length 3 found
7 >>> ord(a) # И именно строку
8 Traceback (most recent call last):
9 File "<stdin>", line 1, in <module>
10 TypeError: ord() expected a character, but string of length 70 found
11 >>> ord("ы") # Символы, не принадлежацие таблице ASCII, кодируются с помощью Юникода
12 1099
13 >>> chr(1099) # chr позволяет по коду символа получить сам символ (символ Юникода тоже)
14 'ы'
15 >>> hex(ord("a")) # Для примера нам потребуются шестнадцатеричные коды символов
16 '0x61'
17 >>> hex(ord("ы"))
18 '0x44b'
19 >>> print("\x61") # \xhh - управляющая последовательность, позволяющая вывести ASCII-символ по его коду
20 a
21 >>> print("\x04\x4b\x61") # Для кириллицы не подойдёт
22 Ka
23 >>> print("\u044b\x61") # Символы юникода задаются с помощью управляющих последовательностей \u и \U (за первой следуют 4 шестнадцатеричные цифры, за второй - 8)
24 ыa
25
В питоне, начиная с третьей версии, по умолчанию строки кодируются в UTF-8 (кстати, по ссылке очень хорошо объяснена предыстория вопроса; почитайте, если плохо понимаете, что есть Юникод и с чем его едят).
2.4. Строка как последовательность
Мы уже знаем, что строка - это последовательность, и, значит, по ней можно пройтись циклом for:
Вопрос.
Что есть элемент этой последовательности?
В кортежах элементом последовательности является элемент кортежа. В строках же элемент последовательности - строка, состоящая из одного (соответствующего) символа:
1 >>> a = "Raxacoricofallapatorius"
2 >>> a[5] # Строка из одного символа
3 'o'
4 >>> a[5:9] # Новая строка из 4 символов
5 'oric'
6 >>> a[8]
7 'c'
8 >>> a[8:9]
9 'c'
10 >>> a[8] is a[8:9] # TODO: В чём принципиальное отличие строки от кортежа, кроме того, что каждый элемент строки - тоже строка? Нужно уточнить
11 True
12 >>> a[8] is 'c'
13 True
14
К слову, напомню, что строки - неизменяемый тип данных:
2.4.1. Операция in
Для строк операция in не осуществляет, как для других последовательностей, поиск первого вхождения элемента (т.е. строки из одного символа). Она осуществляет поиск подстроки в строке:
Поиск подстроки в строке в питоне имеет линейную, а не квадратичную, сложность (спасибо алгоритму Дейкстры).
2.4.2. Операция count
count осуществляет подсчёт количества вхождений подстроки в строку (что тоже является уникальным для строк поведением):
2.5. Методы строк
У строк очень много различных методов, что связано с головными болями, которые разработчики языка имели при работе с ABC/Паскалем:
1 >>> a = "asd aSDFSDv zxcdfg%^ 567567 GFHFG oikpi"
2 >>> dir(a)
3 ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
4
Эти методы делятся на несколько групп.
2.5.1. Поиск
Помимо уже упомянутых in и count, следует знать также об index и find:
1 >>> a
2 'asd aSDFSDv zxcdfg%^ 567567 GFHFG oikpi'
3 >>> a.index("SDF") # Найти индекс первого вхождения подстроки в строку
4 5
5 >>> a.index("SDF!") # Если такой подстроки в строке не содержится, выбросить исключение
6 Traceback (most recent call last):
7 File "<stdin>", line 1, in <module>
8 ValueError: substring not found
9 >>> a.find("SDF") # find тоже находит первое вхождение подстроки в строку
10 5
11 >>> a.find("SDF!") # Однако в случае неуспеха не выбрасывает ошибку, а возвращает -1
12 -1
13
2.5.2. Проверки
Названия методов из этой группы начинаются на is. Сами эти методы призваны проверять различные свойства строк:
1 >>> b = "123we"
2 >>> b.isalnum() # "is alphanumeric" - содержит ли строка только буквы и цифры
3 True
4 >>> b = "123we!"
5 >>> b.isalnum()
6 False
7 >>> b = "123we_" # К слову, нижнее подчёркивание буквой не считается
8 >>> b.isalnum()
9 False
10 >>> b = "йцукен" # Буквами считаются и буквы в Юникоде
11 >>> b.isalnum()
12 True
13 >>> "1234".isdigit() # isdecimal, isdigit, isnumeric - проверка, состоит ли строка из цифр (с некоторыми тонкостями)
14 True
15 >>> "1234".isdecimal()
16 True
17 >>> "1234F".isdecimal()
18 False
19 >>> "1234F".isdigit()
20 False
21 >>> b = "123qwe"
22 >>> b.isidentifier() # Проверка, может ли строка быть идентификатором (именем объекта), т.е. является ли она последовательностью букв, цифр и _, начинающейся не с цифры
23 False
24 >>> b = "_123qwe"
25 >>> b.isidentifier()
26 True
27 >>> "asd".islower() # islower - состоит ли строка только из строчных букв
28 True
29 >>> "aSd".islower()
30 False
31 >>> "ASD".isupper() # isupper - состоит ли строка только из прописных букв
32 True
33 >>> "AsD".isupper()
34 False
35 >>> "word".isprintable() # isprintable - состоит ли строка только из печатных символов
36 True
37 >>> "word\n".isprintable()
38 False
39 >>> "\n\t \t\n".isspace() # isspace - состоит ли строка только из пробельных символов
40 True
41 >>> "\n\t ! \t\n".isspace()
42 False
43 >>> "Avalidtitle".istitle() # istitle - проверяет, состоит ли строка только из слов, разделённых пробелами, состоящих только из букв и начинающихся с прописной буквы каждое
44 True
45 >>> "A nonvalid title".istitle()
46 False
47 >>> "A_non-valid_title".istitle()
48 False
49 >>> "Anon-validtitle".istitle()
50 False
51 >>> "Anon123alidtitle".istitle()
52 False
53 >>> "ANonValidTitle".istitle()
54 False
55 >>> "A Valid Title".istitle()
56 True
57
Про разницу между isdecimal, isdigit и isnumeric можно почитать здесь.
2.5.3. Методы форматирования
1 >>> s = "qWe"
2 >>> s.lower() # lower - преобразование всех букв в строчные
3 'qwe'
4 >>> s.upper() # upper - преобразование всех букв в прописные
5 'QWE'
6 >>> a.capitalize() # capitalize - преобразование первой буквы в прописную
7 'Asd asdfsdv zxcdfg%^ 567567 gfhfg oikpi'
8 >>> a.title() # title - преобразование первых букв всех слов в прописные
9 'Asd Asdfsdv Zxcdfg%^ 567567 Gfhfg Oikpi'
10 >>> s.swapcase() # swapcase - сменить регистр всех букв в строке
11 'QwE'
12 >>> a.casefold() # casefold - привести строку к такому виду, в котором её возможно сравнивать (>, <) с другими строками вне зависимости от регистра букв
13 'asd asdfsdv zxcdfg%^ 567567 gfhfg oikpi'
14
2.5.4. replace
Гораздо более интересный метод - replace. Он позволяет заменить вхождения подстроки на заданную строку:
2.5.5. Работа с пробельными символами
Как убрать лишние пробелы? Методами lstrip, rstrip и strip:
Кроме того, есть метод expandtabs, являющийся наследием второго питона и позволяющий раскрыть символы табуляции в строке по определённым правилам.
2.5.6. zfill
Метод zfill позволяет дополнить строку, состоящую из цифр, нулями слева, чтобы получить строку длины не меньше указанной:
2.6. split и join
Самые интересные и полезные методы работы со строками я даже выделил в отдельный раздел.
2.6.1. split
Метод split позволяет разбить строку на части по какому-либо символу (по умолчанию - по целым подпоследовательностям, состоящим из пробельных символов). При этом результатом его работы будет список подстрок исходной строки:
1 >>> a
2 'asd aSDFSDv zxcdfg%^ 567567 GFHFG oikpi'
3 >>> a.split() # Разбить строку на подстроки по пробельным символам (последовательность пробельных символов как бы считается за один символ)
4 ['asd', 'aSDFSDv', 'zxcdfg%^', '567567', 'GFHFG', 'oikpi']
5 >>> nn = "123 32 2134 346 657 56 1234 436" # Это очень удобно для анализа ввода с клавиатуры
6 >>> [int(n) for n in nn.split()]
7 [123, 32, 2134, 346, 657, 56, 1234, 436]
8 >>> nn.split("3") # Можно и указать подстроку, по которой выполнять разбиение
9 ['12', ' ', '2 21', '4 ', '46 657 56 12', '4 4', '6']
10 >>> a = "a,,d,r,,,e,,r" # Если вы указываете подстроку, по которой разбивать данную, вы можете получить в массиве и пустые строки
11 >>> a.split(",")
12 ['a', '', 'd', 'r', '', '', 'e', '', 'r']
13 >>> a.split(",,") # Эта подстрока, конечно, не обязана состоять из одного символа
14 ['a', 'd,r', ',e', 'r']
15
Метод split очень, ОЧЕНЬ часто используется при анализе входных данных с клавиатуры.
Частный случай работы метода split, с некоторыми нюансами (например, независимость от используемого в ос символа новой строки), представляет метод splitlines:
2.6.2. join
Можно выполнить и обратную операцию - объединить несколько строк в одну:
1 >>> sn = nn.split()
2 >>> "__".join(sn) # Таким образом можно задать тот разделитель, которым нужно соединять строки
3 '123__32__2134__346__657__56__1234__436'
4 >>> "".join(sn) # Т.к. join - метод строки, то, даже если нам не нужен разделитель, хотя бы пустую строку указать придётся
5 '123322134346657561234436'
6
Может возникнуть вопрос: зачем это делать с помощью отдельного метода, если есть операция конкатенации +?
Эффективность. Если только вы хотите объединить не две строки, а больше, попытка сделать это через конкатенацию приведёт к тому, что на каждую конкатенацию двух строк интерпретатор создаст отдельный объект (даже если записать всё выражение в виде "a + b + c + d + ...").
В CPython эту проблему обходят с помощью хака, но вообще полагаться на эффективную реализацию конкатенации строк не стоит (но и ради сложения двух строк использовать join смысла нет).
В интернетах если не продолжаются до сих пор, то, по крайней мере, легко находятся старые холивары на тему того, какой метод эффективнее, и не всегда наиболее оцененный комментарий - верный. Так что будьте аккуратны, сверяйтесь с несколькими источниками и не забывайте проверять даты публикаций.
2.7. Форматирование строк
Пока не заполнено - посмотрите, что мы уже знаем про форматирование строк.