Python — strings

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random
Random Intro
Data Distribution
Random Permutation
Seaborn Module
Normal Distribution
Binomial Distribution
Poisson Distribution
Uniform Distribution
Logistic Distribution
Multinomial Distribution
Exponential Distribution
Chi Square Distribution
Rayleigh Distribution
Pareto Distribution
Zipf Distribution

NumPy ufunc
ufunc Intro
ufunc Create Function
ufunc Simple Arithmetic
ufunc Rounding Decimals
ufunc Logs
ufunc Summations
ufunc Products
ufunc Differences
ufunc Finding LCM
ufunc Finding GCD
ufunc Trigonometric
ufunc Hyperbolic
ufunc Set Operations

String Format

As we learned in the Python Variables chapter, we cannot combine strings and numbers like this:

Example

age = 36txt = «My name is John, I am » + ageprint(txt)

But we can combine strings and numbers by using the method!

The method takes the passed arguments,
formats them, and places them in the string where the placeholders
are:

Example

Use the method to insert numbers
into strings:

age = 36txt = «My name is John, and I am {}»print(txt.format(age))

The format() method takes unlimited number of arguments, and are placed into
the respective placeholders:

Example

quantity = 3itemno = 567price = 49.95myorder = «I want {}
pieces of item {} for {} dollars.»print(myorder.format(quantity,
itemno, price))

You can use index numbers to be sure the arguments are placed
in the correct placeholders:

Example

quantity = 3itemno = 567price = 49.95myorder = «I want to pay {2}
dollars for {0} pieces of item {1}.»print(myorder.format(quantity,
itemno, price))

String Formatting Operator

One of Python’s coolest features is the string format operator %. This operator is unique to strings and makes up for the pack of having functions from C’s printf() family. Following is a simple example −

#!/usr/bin/python3

print ("My name is %s and weight is %d kg!" % ('Zara', 21)) 

When the above code is executed, it produces the following result −

My name is Zara and weight is 21 kg!

Here is the list of complete set of symbols which can be used along with % −

Sr.No. Format Symbol & Conversion
1

%c

character

2

%s

string conversion via str() prior to formatting

3

%i

signed decimal integer

4

%d

signed decimal integer

5

%u

unsigned decimal integer

6

%o

octal integer

7

%x

hexadecimal integer (lowercase letters)

8

%X

hexadecimal integer (UPPERcase letters)

9

%e

exponential notation (with lowercase ‘e’)

10

%E

exponential notation (with UPPERcase ‘E’)

11

%f

floating point real number

12

%g

the shorter of %f and %e

13

%G

the shorter of %f and %E

Other supported symbols and functionality are listed in the following table −

Sr.No. Symbol & Functionality
1

*

argument specifies width or precision

2

left justification

3

+

display the sign

4

<sp>

leave a blank space before a positive number

5

#

add the octal leading zero ( ‘0’ ) or hexadecimal leading ‘0x’ or ‘0X’, depending on whether ‘x’ or ‘X’ were used.

6

pad from left with zeros (instead of spaces)

7

%

‘%%’ leaves you with a single literal ‘%’

8

(var)

mapping variable (dictionary arguments)

9

m.n.

m is the minimum total width and n is the number of digits to display after the decimal point (if appl.)

Создание объекта dict, принимающего только целые и плавающие числа в качестве значений

В этом сценарии мы реализуем класс, который создает объекты-словари, принимающие только целые и плавающие значения.

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

Для реализации этого процесса используются следующие методы:

__int__, __setitem__ и __str __

Для начала создаем пользовательский класс CustomIntFloat и передаем dict в список наследования аргументов. Это означает, что созданный объект будет вести себя как словарь, за исключением тех мест, в которых это поведение будет выборочно изменено.

Затем создаем метод __init__, чтобы сконструировать объект dict CustomIntFloat, который принимает ключ и значение в список аргументов, установленный в тип None по умолчанию. Таким образом, если пользователь создает объект класса CustomIntFloat без передачи ключа или значения, будет сгенерирован пустой dict. Данное условие гласит: если ключ не передан, то параметру ключа по умолчанию присваивается аргумент None, а пустой dict создается путем ссылки на объект CustomIntFloat с атрибутом класса empty_dict.

Если пользователь указывает ключ length и соответствующее значение, которое является экземпляром класса int или float, то ключ и значение будут установлены в объекте.

Наконец, если пользователь указывает несколько ключей и значений в качестве итерируемых в операторе else, то они будут заархивированы функцией zip и им будет присвоено имя переменной zipped. Выполняем цикл на zipped, чтобы проверить, имеет ли значение тип int или float. Если нет, то будет сгенерировано пользовательское исключение CustomIntFloatError.

Класс исключения CustomIntFloatError и метод __str__

При генерации исключения CustomIntFloatError создается экземпляр класса CustomIntFloatError.

Таким образом, этот пользовательский класс исключений нуждается в помощи magic-методов __init__ и __str__. Созданный экземпляр принимает переданное значение и устанавливает его в качестве значения атрибута в классе CustomIntFloatError.

Это означает, что при появлении сообщения об ошибке значение, переданное в __init__ объекта CustomIntFloat, может быть установлено как атрибут (self.value) в классе CustomIntFloatError и с легкостью проверено.

Если ввод неверный, то появляется исключение CustomIntFloatError, а объект не создается. Сообщение об ошибке информирует пользователя о том, что допустимыми являются только целые и плавающие значения.

Аналогичным образом при попытке создать экземпляр объекта z (который был закомментирован) с несколькими ключами и значениями, возникает то же исключение, информирующее пользователя о том, что ‘three’ не является допустимым вводом.

Метод __setitem__

__setitem__ — это magic-метод, который вызывается при установке ключа и значения в словаре. Если после создания объекта CustomIntFloat пользователь попытается добавить значение, которое не относится к типу int или float, появится то же исключение CustomIntFloatError. Ниже показано, как установить ключ и значение:

В результате недопустимого ввода возникает исключение CustomIntFloatError:

Исходный код:

Обзор класса CustomIntFloat

С помощью наследования через такие встроенные классы, как dict, можно настраивать поведение через повторную реализацию magic-методов. У этого подхода есть множество преимуществ.

Стоит отметить, что пользователю не нужно изучать новый синтаксис. Он может добавить ключ и значение к объекту dict CustomIntFloat привычным образом. Единственным отличием является выбор допустимых значений типа int и float. Если пользователь указывает любой другой тип, то сообщение об ошибке информирует его об этом и указывает допустимые типы значений.

Кодировки

Другим любопытным моментом является то, что символы которые мы видим внутри строки на самом деле являются порядковыми номерами в таблице которая ставит в соответсвие этому номеру определенный сивол. Эти таблицы мы называем кодировками. Существует очень много кодировок, но возможно вы слышали названия некоторых из них: ASCII, Latin-1, КОИ-8, utf-8. По умолчанию, в Python используется стандарт «Юникод». И в том что каждому символу соответствует определенный код очень легко убедиться с помощью встроенных функций и :

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

Чтож, похоже что программа-отправитель использует какуюто другую кодировку. Допустим, мы смогли выяснить, что до того как эта строка стала набором байтов ее напечатали на русском языке. Русский язык поддерживают многие кодировки. Придется пробовать декодировать в каждую из них. Поехали…

Какя-то абракадабра. Пробуем следующую:

Как видите, байтовые строки не несут информации о своей кодировке, хотя в зависимости от происхождения, эта кодировка может быть какой угодно. Рассмотренная проблема встречается очень редко, но все же встречается. Многие научные программы до сих пор используют кодировку ascii по умолчанию, а некоторые операционные системы могут использовать какую-то другую кодировку. Вообще, кодировкой по умолчанию является кодировка операционной системы (можно узнать с помощью функции модуля sys). Так что, если вы создаете интернациональное приложение или сайт, или не знаете с какой операционкой придется работать вашей программе, то наверняка тоже встретитесь с этой проблемой. Повторюсь, проблема редкая, весьма специфичная и Python предоставляет относительно неплохие средства для ее преодоления.

Чтож, вот мы и познакомились со строками. Определение, которое мы дали в начале, могло показаться очень сложным и непонятным (я даже не совсем уверен в его правильности), но тем не менее, на деле, все оказалось довольно простым.

6.3 String Pool

Все строки, которые были заданы в коде в , во время работы программы хранятся в памяти в так называемом . — это специальный массив для хранения строк. Цель его создания — оптимизация хранения строк:

Во-первых, строки, заданные в коде, нужно все-таки где-то хранить. Код — это команды, а данные (тем более такие большие как строки) нужно хранить в памяти отдельно от кода. В коде фигурируют только ссылки на объекты-строки.

Во-вторых, все одинаковые литералы можно хранить в памяти только один раз. Так оно и работает. Когда код вашего класса загружается Java-машиной, все строковые литералы добавляются в , если их там еще нет. Если уже есть, просто используется ссылка на строку из .

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

Как это примерно работает:

Код Работа с StringPoll

Именно поэтому переменные и будут хранить одинаковые ссылки.

Метод

Ну и самое интересное: вы можете программно добавить любую строку в . Для этого нужно просто вызвать метод у -переменной.

Метод добавит строку в , если ее еще там нет, и вернет ссылку на строку из .

Код Примечание

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *