====== Числа, Cтроки, RegExp ====== ===== Числа ===== Операции над числами разных типов возвращают **число в более сложном типе**\\ Числа можно записывать в **двоичном**, **восьмеричном** и **шестнадцатеричном** виде, они **автоматом будут приведены** к десятичной форме\\ * **Двоичное** - начинаются с символов **0b (0B)** * **Восьмеричное** - начинаются с символов **0о (0О)** * **Шестнадцатеричное** - начинаются с символов **0x (0X)** * **Вещественное** - содержит точку либо символ **Е (е)**, есть модуль/функция **Decimal**, для фиксированной точности * **Дробное** - модуль/функция **Fraction** * **Комплексное** - <Вещественная часть> + <Мнимая>J (j) 0b101101 # 45 0o12 # 10 0xA # 10 .14 # 0.14 Fraction(1,2); Fraction("0.5") # дробь, одна вторая # в python 3.6, для удобства, можно добавлять подчеркивание 0b1111_1111 # 255 ==== Функции и методы ==== * **int(), float(), bin(), oct(), hex()** - преобразование (целое, вещественное, двоичное, восьмеричное, шестнадцатеричное с-но) * **round(<Число>,<Кол-во знаков после запятой>=0)** - округление * **abs()** - абсолютное число * **pow(<Число>, <Степень>, <Делитель>=)** - возведение в степень * **max(), min()** - принимает список чисел через запятую * **sum(<Последовательность>,<Нач значение>=0)** - принимает списки, кортежи и т.д. * **divmod(x,y)** - возвращает кортеж из двух значений Float так же поддерживает * **is_integer()** - если нет дробной части * **as_integer_ration()** - вернет два числа, целую и дробную части ==== Модуль math ==== Содержит константы типа **pi**, **e** и т.д.\\ Функции типа **sin(), cos(), tan(), exp(), log(), pow(), fmod(), fsum(), factorials**и т.д.\\ ==== Модуль random ==== * **random()** - псевдослучайное число от 0.0 до 1.0 * **seed(<Параметр>, <версия>=2)** - настраивает генератор на новую последовательность * **choice(<Последовательность>)** - случайный выбор из заданной последовательности (строка, список, кортеж и т.д.) * **suffle()** - перемешивает заданную последовательность, сохраняя изменения в объекте * **uniform(<Начало>, <Конец>)/randint(<Начало>, <Конец>)** - псевдослучайное вещественное/целое, в диапазоне * **randrange(<Начало>=0, <Конец>, <Шаг>=1)** - из диапазона, тут же его генерирует random.random() random.seed(10) random.choice("String") random.randrange(100,2) ===== Строки и двоичные данные ===== Длинна строки ограничивается лишь объемом ОЗУ\\ Как и все последовательности поддерживает обращение по индексу, конкатенацию, срез, проверка на вхождение и т.д.\\ **Неизменяемый** тип данных т.е. методы **возвращают новую строку**, а не сам элемент, который можно изменить.\\ **Нулевой символ не является концом строки**\\ * **str** - Unicode строка, при выводе можно указывать кодировку * **bytes** - неизменяемая последовательность байт, элементы хранят значения 0..255, поддерживает большинство методов строк, доступ по индексу возвращает целое число, а не символ. Может содержать как однобайтовые так и многобайтовые символы * **bytearray** - изменяемая последовательность байт ==== Создание строки ==== Если преобразовывать из bytes/bytearray, то необходимо указывать кодировку в функции **str()**, так же, она принимает параметры исключений, третьим параметром\\ **Разницы между двойными кавычками и апострофами нет**\\ Спец символы экранируются слешем либо символом **r** перед строкой\\ **Тройные кавычки** (апострофы) сохраняют все форматирование, добавляются в документацию (func.__doc__), печатают все спец символы\\ **Конкатенация** может происходить слешем, плюсом, внутри скобок\\ ==== Спец символы ==== Типа: n,r,t,v,a,b,f - перевод строки/каретки, табуляция/вертикальная, звонок/забой оО ?, перевод формата и т.д.\\ Пишутся после слеша с-но\\ ==== Операции над строками ==== Обращение по индексу, если индекс отсутствует - исключение **IndexError**\\ В индексе можно указать **отрицательное значение**, тогда отсчет **идет с конца** (значение отнимается от длинны строки)\\ Полезен метод **извлечения среза**, все параметры необязательны, возвращается копия строки\\ [<Начало>:<Конец>:<Шаг>] s= Python s[:] # вся строка s[::-1] # в обратном порядке "J"+ s[1:] # замена первого символа s[:-1] # удалить последний символ s[0:1]; s[-1:] # получить первый (последний) s[2:5] # часть строки ==== Форматирование строк ==== <Строка специального формата> % <Значение> %[(<Ключ>)] [<Флаг>] [<Ширина>] [.<Точность>] <Тип преобразования> "%s - %s - %s" % (10,20,30) # '10 - 20 - 30' # <Ключ> - ключ словаря, в этом случае должен быть указан словарь "%(name)s - %(year)s" % {"year": 1978, "name": "Nil"} # <Флаг> - флаг преобразования (пробелы, нули, системы счисления) # <Ширина> - мин ширина поля === Метод format() === В последующих версиях python знак **%** перестанет использоваться, рекомендуется использовать этот метод <Строка> = <Строка спец формата>.format(*args, **kwargs) {[<Поле>] [!<Функция>] [:<Формат>]} "{0} - {1} - {2}".format(10, 12.3, "String") # '10 - 12.3 String' ==== Форматируемые строки ==== В python 3.6 есть альтернатива методу **format()**, т.н. "Форматируемая строка", она обязательно предваряется символом **f (F)**, и вставляет переменные у казанные места.. типа того {[<Переменная>] [!<Функция>] [:<Формат>]} a= 10; b= 12.3; s= "string" f"{a} - {b} - {s}" # Еще вариант вставки переменных в строку print("{0} - {1}".format(1, 2)) ==== Функции и методы строк ==== * **strip()** - удаляет указанные символы в начале и конце строки (если не указано то пробелы удаляет) * **l[r]strip()** - тоже самое только вначале (в конце) строки * **split(<Разделитель>=пробел, <Лимит>= )** - разбивает на подстроки * **rsplit()** - справа на лево * **splitlines(- не включать разделить в результат)** - разбивает по строкам (символ переноса строки) * **join()** - собирает строку "<строка> = <разделитель>.join(<последовательность>)" - :!: п*дарастическая ф-я, непонятки с кодировкой после нее " => ".join(["one", "two", "three"]) # 'one => two => three' ==== Локаль ==== **locate(<категория>, <локаль>= )**\\ Модуль **locale**, устанавливать несколько раз.\\ Установить можно командой **locate.setlocate(<Категория>)**, получить текущую **locate.getlocate(<Категория>)**, получить настройки локали можно **locate.localeconv()**\\ * **locate.LC_ALL** - для всех режимов * **locate.LC_COLLATE** - для сравнения строк * **locate.LC_CTYPE** - для перевода регистра * **locate.LC_MONETARY** - для денежных единиц * **locate.LC_NUMERIC** - для чисел * **locate.LC_TIME** - для даты/время ==== Регистр символов ==== **upper(), lower(), swapcase(), capitalize(), title(), casefold()**- верхний/нижний/противоположный регистры, первая буква заглавная, тоже но для каждого слова, заменяет расширенные символы буквами, полезно при сравнении строк.\\ ==== Функции и методы символов ==== **chr(), ord()**- возвращает символ указанного кода, и код указанного символа\\ ==== Поиск и замена ==== * **find()** - возвращает номер позиции с которой начинается подстрока или -1 если ее нет, **чувствителен к регистру**. <строка>.find(<подстрока>, <начало>=, <конец>= ), если начало и конец указаны, поиск производится в срезе * **index()** - аналогично, но вызовет исключение если подстроки нет * **rfind()/rindex()** - аналогично но возвращает номер последнего вхождения * **count()** - кол-во вхождений * **startswith()/endswith()** - начинается (заканчивается) ли строка с указанной подстроки * **replace()** - возвращает новую строку. <строка>.replace(<подстрока>, <новая подстрока>, <мах кол-во замены>= ) * **translate(<таблица символов>)** - в аргументе принимает словарь, собсна заменяет все указанные символы соответствующими, "None"- удаляет. В ключе словаря должен быть указано Unicode номер символа, с этим может помочь метод **maketrans(dict)**. Для удаления можно указать целую строку символов, третьим параметром ==== Проверка типа содержимого строки ==== Есть рад функций типа **isalnum()**, **isalpha()**, **isdigit()**, **isdecimal()**, **isnumeric()**, **isupper()**, **istitle()** и т.д., для проверки содержимого\\ ==== bytes ==== Хранит в себе неизменяемую последовательность байт, от 0..255, можно хранить бинарные данные, поддерживает множество строковых методов\\ **bytearray**- впринципе тоже самое, но последовательность изменяемая\\ ==== Преобразование ==== Преобразовать объект в последовательность байтов (т.е. выполнить сериализацию/десериализацию) можно с помощью **модуля pickle**\\ * **dump(<Объект>, <протокол>=, =True)** - возвращает последовательность байт, в соответствии с протоколом * **load(<последовательность байт>, =True, =ASCII, )** - обратное д-е ==== Шифрование ==== Модуль **hashlib**\\ Функции типа **md5()**, **sha1,224,256,384()**, в 3.6 появились еще **sha3_224,256,512()** и т.д. ===== Регулярные выражения ===== **import re**\\ [[https://python.ivan-shamaev.ru/python-3-regular-expressions-regex-match-group-string|Дока]]\\ ==== Синтаксис ==== Шаблон нужно компилировать ф-ей **compile()**\\ :!: Символ **r** перед строкой позволяет не экранировать спец символы\\ <Шаблон>= re.compile(<Рег выражение>, <Модификатор>=) p= re.compile(r"^[а-я]+$") if p.search("Input string"): # Либо if re.search("^[а-я]+$", "Input string"): Модификаторы: * **I (IGNORECASE)** - регистр * **M (MULTILINE)** - текст с подстроками, символы ^ и $ относятся к подстрокам * **S (DOTALL)** - если указать, то символ точка соответсвует переводу стоки.. оО * **X (VERBOSE)** - пробелы и перевод строки игнорируется Экранирование слешем (\) или в квадратных скобках re.compile(r"^[0-3][0-9]\.[01][0-9]\.[12]$") re.compile(r"^[0-3][0-9][.][01][0-9][.][12]$") Символы ^ и $ зависят от модификаторов (M или S), \A и \Z- аналогичные, но не зависят от модификаторов\\ p= re.compile(r"^.+$") Точка не соответствует \n p.findall("Str1\nStr2\nStr3") # Ничего не найдено p= re.compile(r"^.+$", re.S) # Теперь соответствует p.findall("Str1\nStr2\nStr3") # Найдена все строка, целиком p= re.compile(r"^.+$", re.M) # Многострочный режим p.findall("Str1\nStr2\nStr3") # list из трех подстрок p= re.compile(r"Красн((ая)|(ое))") p.search("Красное") # Позиция для поиска p= re.compile(r"\bPython\b") p.search("Python") p= re.compile(r"\Bthon\b") p.search("Python") Вместо символов можно использовать классы: * **\d** - цифры * **\w** - цифры и буква * **\s** - любой пробельный символ * **\D, \W, \S** - тоже самое, ток отрицание * **\b** - начало слова * **\B** - не начало слова Число вхождений, типа: * **{n}, {n,}, {n,m}** - ровно **n**, **n** и более, от **n** до **m** * ***** - ноль или более * **+** - одно или более * **?** - ни одного Ищется самая длинная строка, пропуская более короткие соответствия, чтобы ограничить, нужно указать ?\\ Получить содержимое тегов '
' вместе с тегами: s= '
Text1
Text2
Text3
' p= re.compile(r"
.*
", re.S) p.findall(s) >> ['
Text1
Text2
Text3
'] # Получили всю строку p= re.compile(r"
.*?
", re.S) # Ограничили "Жадность" p.findall(s) >> ['
Text1
', '
Text3
'] p= re.compile(r"
(.*?)
", re.S) # Добавили скобки p.findall(s) >> ['Text1', 'Text3'] # Результат без тегов !!!
Скобки **группируют фрагменты**, чтобы отбросить из результата сами фрагменты, нужно указать **?:** внутри скобок\\ Например (?:tx) найдет и "Text" и "tx", чтобы второго не было, нужно указать **?:**\\ К найденному фрагменту можно обратится, по порядковому номеру или по имени, номера есть по умолчанию- **\№**\\ Например получим текст между одинаковыми тегами: s= 'Text1 Text4 Text2 Text3' p= re.compile(r"<([a-z]+)>(.*?)", re.S | re.I) p.findall(s) >> [('b', 'Text1'), ('I', 'Text2'), ('b', 'Text3')] # ?P - для задания имени фрагменту s= 'eed 34 dc 3455' p= re.compile(r"(?P[0-9]+) (?P[a-z]+)", re.I) p.search(s) p.group('digit') >> '34' # Пока точно не уверен на чет результата, нужно больше углубления ==== Поиск первого совпадения ==== Для этого есть следующе методы (и функции их аналоги): * **match()** - соответствие с началом строки * **search()** - соответствие с любой частью строки * **fullmatch()** - соответствие со всей строкой Объект **Match** содержит следующие свойства и методы: * **re** - ссылка на скомпилированный шаблон, в ней есть следующие атрибуты: * **groups (groupindex)** - кол-во групп в шаблоне (перечисление в словаре) * **pattern** - строка с рег выражением * **flags** - комбинация флагов * **string** - строка .. оО * **pos (endpos)** - начальная/конечная позиции * **lastindex (lastgroup)** - пар-ры последней группы * **group (groups, groupdict)** - фрагменты, соответствующие шаблону * **start (end)** - начало/окончание фрагмента * **span** - кортеж с начальным и конечным индексами фрагмента * **expand** - замена в строке ==== Поиск всех совпадений ==== Это так же функции и методы: * **findall()** - возвращает список (строк или кортежей), ищет все соответствия * **finditer()** - возвращает итератор, на каждой итерации возвращает **Match** ==== Замена в строке ==== Метод **sub()** ищет все совпадения и заменяет указанным значением\\ sub[<Новый фрагмент или ссылка на функцию>, <Строка для замены>, <Мах кол-во замен>=] Внутри нового фрагмента можно использовать **обратные ссылки** типа (\номер элемента \g название группы \g номер группы)\\ # Поменяем два тега местами p= re.compile(r"<(?P[a-z]+)><(?P[a-z]+)>") print(p.sub(r"<\2><\1>", "

")) print(p.sub(r"<\g<2>><\g<1>>", "

")) print(p.sub(r"<\g><\g>", "

")) # Функция для замены def repl(match): x= int(match.group(0)) x += 10 return "{0}".format(x) p= re.compile(r"[0-9]+") print(p.sub(repl, "2008, 2009, 2010, 2011"))
==== Прочие функции и методы ==== * **split()** - разбивка строки * **escape()** - экранирует все символы (re.escape(r"[]{}.")) * **purge()** - очистка кэша рег выражений