Какие математические операторы можно применять для двух объектов формата str
Перейти к содержимому

Какие математические операторы можно применять для двух объектов формата str

  • автор:

Преобразование типов

Чаще всего операторы и функции автоматически приводят переданные им значения к нужному типу.

Например, alert автоматически преобразует любое значение к строке. Математические операторы преобразуют значения к числам.

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

Пока что мы не говорим об объектах

В этой главе мы не касаемся объектов. Сначала мы разберём преобразование примитивных значений.

Мы разберём преобразование объектов позже, в главе Преобразование объектов в примитивы.

Строковое преобразование

Строковое преобразование происходит, когда требуется представление чего-либо в виде строки.

Например, alert(value) преобразует значение к строке.

Также мы можем использовать функцию String(value) , чтобы преобразовать значение к строке:

let value = true; alert(typeof value); // boolean value = String(value); // теперь value это строка "true" alert(typeof value); // string

Преобразование происходит очевидным образом. false становится «false» , null становится «null» и т.п.

Численное преобразование

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

Например, когда операция деления / применяется не к числу:

alert( "6" / "2" ); // 3, строки преобразуются в числа

Мы можем использовать функцию Number(value) , чтобы явно преобразовать value к числу:

let str = "123"; alert(typeof str); // string let num = Number(str); // становится числом 123 alert(typeof num); // number

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

Если строка не может быть явно приведена к числу, то результатом преобразования будет NaN . Например:

let age = Number("Любая строка вместо числа"); alert(age); // NaN, преобразование не удалось

Правила численного преобразования:

Значение Преобразуется в…
undefined NaN
null 0
true / false 1 / 0
string Пробельные символы (пробелы, знаки табуляции \t , знаки новой строки \n и т. п.) по краям обрезаются. Далее, если остаётся пустая строка, то получаем 0 , иначе из непустой строки «считывается» число. При ошибке результат NaN .
alert( Number(" 123 ") ); // 123 alert( Number("123z") ); // NaN (ошибка чтения числа на месте символа "z") alert( Number(true) ); // 1 alert( Number(false) ); // 0

Учтите, что null и undefined ведут себя по-разному. Так, null становится нулём, тогда как undefined приводится к NaN .

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

Логическое преобразование

Логическое преобразование самое простое.

Происходит в логических операциях (позже мы познакомимся с условными проверками и подобными конструкциями), но также может быть выполнено явно с помощью функции Boolean(value) .

  • Значения, которые интуитивно «пустые», вроде 0 , пустой строки, null , undefined и NaN , становятся false .
  • Все остальные значения становятся true .
alert( Boolean(1) ); // true alert( Boolean(0) ); // false alert( Boolean("Привет!") ); // true alert( Boolean("") ); // false

Заметим, что строка с нулём «0» — это true

Некоторые языки (к примеру, PHP) воспринимают строку «0» как false . Но в JavaScript, если строка не пустая, то она всегда true .

alert( Boolean("0") ); // true alert( Boolean(" ") ); // пробел это тоже true (любая непустая строка это true)

Итого

Существует 3 наиболее широко используемых преобразования: строковое, численное и логическое.

Строковое – Происходит, когда нам нужно что-то вывести. Может быть вызвано с помощью String(value) . Для примитивных значений работает очевидным образом.

Численное – Происходит в математических операциях. Может быть вызвано с помощью Number(value) .

Преобразование подчиняется правилам:

Значение Становится…
undefined NaN
null 0
true / false 1 / 0
string Пробельные символы по краям обрезаются. Далее, если остаётся пустая строка, то получаем 0 , иначе из непустой строки «считывается» число. При ошибке результат NaN .

Логическое – Происходит в логических операциях. Может быть вызвано с помощью Boolean(value) .

Значение Становится…
0 , null , undefined , NaN , «» false
любое другое значение true

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

  • undefined при численном преобразовании становится NaN , не 0 .
  • «0» и строки из одних пробелов типа » » при логическом преобразовании всегда true .

В этой главе мы не говорили об объектах. Мы вернёмся к ним позже, в главе Преобразование объектов в примитивы, посвящённой только объектам, сразу после того, как узнаем больше про основы JavaScript.

Числа

С числами можно выполнять различные математические операции.

In [9]: 1+2 Out[9]: 3

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

In [10]: round(10/3.0, 2) Out[10]: 3.33
In [11]: 10 > 3.0 Out[11]: True

Функция int() позволяет выполнять конвертацию в тип int. Во втором аргументе можно указывать систему счисления:

In [12]: a = '11' In [13]: int(a) Out[13]: 11

Если указать, что строку a надо воспринимать как двоичное число, то результат будет таким:

In [14]: int(a, 2) Out[14]: 3

Конвертация в int типа float:

In [19]: int(3.333) Out[19]: 3

Функция bin позволяет получить двоичное представление числа (обратите внимание, что результат — строка):

In [20]: bin(8) Out[20]: '0b1000'

Аналогично, функция hex() позволяет получить шестнадцатеричное значение:

In [21]: hex(10) Out[21]: '0xa'

несколько преобразований одновременно:

In [23]: int('ff', 16) Out[23]: 255 In [24]: bin(int('ff', 16)) Out[24]: '0b11111111'

Для более сложных математических функций в Python есть модуль math:

In [25]: import math In [26]: math.sqrt(9) Out[26]: 3.0 In [27]: math.pi Out[27]: 3.141592653589793

Строки (Strings)

Строка в Python это:
— последовательность символов, заключенная в кавычки
— неизменяемый упорядоченный тип данных

In [28]: 'hello' Out[28]: 'hello' In [29]: tunnel = """ . interface Tunnel0 . ip address 10.10.10.1 255.255.255.0 . tunnel source FastEthernet1/0 . tunnel protection ipsec profile DMVPN . """ In [30]: tunnel Out[30]: '\ninterface Tunnel0\nip address 10.10.10.1 255.255.255.0\ntunnel source FastEthernet1/0\ntunnel protection ipsec profile DMVPN\n'

Строки можно суммировать. Тогда они объединяются в одну строку:

In [32]: intf = 'interface' In [33]: tun = 'Tunnel0' In [34]: intf + tun Out[34]: 'interfaceTunnel0' In [35]: intf + ' ' + tun Out[35]: 'interface Tunnel0'

Строку можно умножать на число. В этом случае, строка повторяется указанное количество раз:

In [36]: intf * 5 Out[36]: 'interfaceinterfaceinterfaceinterfaceinterface'

То, что строки являются упорядоченным типом данных, позволяет обращаться к символам в строке по номеру, начиная с нуля:

In [37]: string1 = 'interface FastEthernet1/0' In [38]: string1[0] Out[38]: 'i'

Нумерация всех символов в строке идет с нуля. Но, если нужно обратиться к какому-то по счету символу, начиная с конца, то можно указывать отрицательные значения (на этот раз с единицы).

In [39]: string1[1] Out[39]: 'n' In [40]: string1[-1] Out[40]: '0'

Кроме обращения к конкретному символу, можно делать срезы строк, указав диапазон номеров (срез выполняется по второе число, не включая его):

In [41]: string1[0:9] Out[41]: 'interface' In [42]: string1[10:22] Out[42]: 'FastEthernet'

Если не указывается второе число, то срез будет до конца строки:

In [26]: string1[10:] Out[26]: 'FastEthernet1/0'

Срезать три последних символа строки:

In [43]: string1[-3:] Out[43]: '1/0'

Также в срезе можно указывать шаг. Так можно получить нечетные числа:

In [44]: a = '0123456789' In [45]: a[1::2] Out[45]: '13579'
In [31]: a[::2] Out[31]: '02468'

Функция len позволяет получить количество символов в строке:

In [46]: line = 'interface Gi0/1' In [47]: len(line) Out[47]: 15

Функция и метод отличаются тем, что метод привязан к объекту конкретного типа, а функция, как правило, более универсальная и может применяться к объектам разного типа. Например, функция len может применяться к строкам, спискам, словарям и так далее, а метод startswith относится только к строкам.

Методы upper, lower, swapcase, capitalize

Методы upper(), lower(), swapcase(), capitalize() выполняют преобразование регистра строки:

In [25]: string1 = 'FastEthernet' In [26]: string1.upper() Out[26]: 'FASTETHERNET' In [27]: string1.lower() Out[27]: 'fastethernet' In [28]: string1.swapcase() Out[28]: 'fASTeTHERNET' In [29]: string2 = 'tunnel 0' In [30]: string2.capitalize() Out[30]: 'Tunnel 0'

Очень важно обращать внимание на то, что часто методы возвращают преобразованную строку. И, значит, надо не забыть присвоить ее какой-то переменной (можно той же).

In [31]: string1 = string1.upper() In [32]: print(string1) FASTETHERNET

Метод count

Метод count() используется для подсчета того, сколько раз символ или подстрока встречаются в строке:

In [33]: string1 = 'Hello, hello, hello, hello' In [34]: string1.count('hello') Out[34]: 3 In [35]: string1.count('ello') Out[35]: 4 In [36]: string1.count('l') Out[36]: 8

Метод find

Методу find() можно передать подстроку или символ, и он покажет, на какой позиции находится первый символ подстроки (для первого совпадения):

In [37]: string1 = 'interface FastEthernet0/1' In [38]: string1.find('Fast') Out[38]: 10 In [39]: string1[string1.find('Fast')::] Out[39]: 'FastEthernet0/1'

Методы startswith, endswith

Проверка на то, начинается или заканчивается ли строка на определенные символы (методы startswith(), endswith()):

In [40]: string1 = 'FastEthernet0/1' In [41]: string1.startswith('Fast') Out[41]: True In [42]: string1.startswith('fast') Out[42]: False In [43]: string1.endswith('0/1') Out[43]: True In [44]: string1.endswith('0/2') Out[44]: False

Методам startswith() и endswith() можно передавать несколько значений (обязательно как кортеж):

In [1]: "test".startswith(("r", "t")) Out[1]: True In [2]: "test".startswith(("r", "a")) Out[2]: False In [3]: "rtest".startswith(("r", "a")) Out[3]: True In [4]: "rtest".endswith(("r", "a")) Out[4]: False In [5]: "rtest".endswith(("r", "t")) Out[5]: True

Метод replace

Замена последовательности символов в строке на другую последовательность (метод replace()):

In [45]: string1 = 'FastEthernet0/1' In [46]: string1.replace('Fast', 'Gigabit') Out[46]: 'GigabitEthernet0/1'

Метод strip

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

Для того, чтобы избавиться от них, очень удобно использовать метод strip():

In [47]: string1 = '\n\tinterface FastEthernet0/1\n' In [48]: print(string1) interface FastEthernet0/1 In [49]: string1 Out[49]: '\n\tinterface FastEthernet0/1\n' In [50]: string1.strip() Out[50]: 'interface FastEthernet0/1'

По умолчанию метод strip() убирает пробельные символы. В этот набор символов входят: \t\n\r\f\v

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

In [51]: ad_metric = '[110/1045]' In [52]: ad_metric.strip('[]') Out[52]: '110/1045'

Метод strip() убирает спецсимволы и в начале, и в конце строки. Если необходимо убрать символы только слева или только справа, можно использовать, соответственно, методы lstrip() и rstrip().

Метод split

Метод split() разбивает строку на части, используя как разделитель какой-то символ (или символы) и возвращает список строк:

In [53]: string1 = 'switchport trunk allowed vlan 10,20,30,100-200' In [54]: commands = string1.split() In [55]: print(commands) ['switchport', 'trunk', 'allowed', 'vlan', '10,20,30,100-200']

По умолчанию в качестве разделителя используются пробельные символы (пробелы, табы, перевод строки), но в скобках можно указать любой разделитель:

In [56]: vlans = commands[-1].split(',') In [57]: print(vlans) ['10', '20', '30', '100-200']

Полезная особенность метода split с разделителем по умолчанию — строка не только разделяется в список строк по пробельным символам, но пробельные символы также удаляются в начале и в конце строки:

In [58]: string1 = ' switchport trunk allowed vlan 10,20,30,100-200\n\n' In [59]: string1.split() Out[59]: ['switchport', 'trunk', 'allowed', 'vlan', '10,20,30,100-200']

У метода split() есть ещё одна хорошая особенность: по умолчанию метод разбивает строку не по одному пробельному символу, а по любому количеству.

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

При работе со строками часто возникают ситуации, когда в шаблон строки надо подставить разные данные.

Это можно делать объединяя, части строки и данные, но в Python есть более удобный способ — форматирование строк.

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

Существует несколько вариантов форматирования строк:
— с оператором % — более старый вариант
— метод format() — относительно новый вариант
f- -строки — новый вариант, который появился в Python 3.6.

Несмотря на то, что рекомендуется использовать метод format, часто можно встретить форматирование строк и через оператор %.

Форматирование строк с методом format

Пример использования метода format:

In [1]: "interface FastEthernet0/<>".format('1') Out[1]: 'interface FastEthernet0/1'

Специальный символ <> указывает, что сюда подставится значение, которое передается методу format. При этом каждая пара фигурных скобок обозначает одно место для подстановки.

Значения, которые подставляются в фигурные скобки, могут быть разного типа. Например, это может быть строка, число или список:

In [3]: print('<>'.format('10.1.1.1')) 10.1.1.1 In [4]: print('<>'.format(100)) 100 In [5]: print('<>'.format([10, 1, 1,1])) [10, 1, 1, 1]

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

Например, таким образом можно вывести данные столбцами одинаковой ширины по 15 символов с выравниванием по правой стороне:

In [3]: vlan, mac, intf = ['100', 'aabb.cc80.7000', 'Gi0/1'] In [4]: print("15> 15> 15>".format(vlan, mac, intf)) 100 aabb.cc80.7000 Gi0/1

Выравнивание по левой стороне:

In [5]: print(" ".format(vlan, mac, intf)) 100 aabb.cc80.7000 Gi0/1

Шаблон для вывода может быть и многострочным:

In [6]: ip_template = ''' . IP address: . <> . ''' In [7]: print(ip_template.format('10.1.1.1')) IP address: 10.1.1.1

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

In [9]: print("".format(10.0/3)) 3.333

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

In [11]: ' '.format(192, 100, 1, 1) Out[11]: '11000000 1100100 1 1'
In [12]: ' '.format(192, 100, 1, 1) Out[12]: '11000000 1100100 1 1'

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

In [13]: ' '.format(192, 100, 1, 1) Out[13]: '11000000 01100100 00000001 00000001'

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

In [15]: '/'.format(mask=24, ip='10.1.1.1') Out[15]: '10.1.1.1/24'

Еще одна полезная возможность форматирования строк — указание номера аргумента:

In [16]: '/'.format(24, '10.1.1.1') Out[16]: '10.1.1.1/24'

python_15_ciscomaster.ru.jpg

За счет этого, например, можно избавиться от повторной передачи одних и тех же значений:

python_16_ciscomaster.ru.jpg

В примере выше октеты адреса приходится передавать два раза — один для отображения в десятичном формате, а второй — для двоичного.
Указав индексы значений, которые передаются методу format, можно избавиться от дублирования:

Форматирование строк с помощью f-строк

В Python 3.6 добавился новый вариант форматирования строк — f-строки или интерполяция строк. F-строки позволяют не только подставлять какие-то значения в шаблон, но и позволяют выполнять вызовы функций, методов и т.п.

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

F-строки — это литерал строки с буквой f перед ним. Внутри f-строки в паре фигурных скобок указываются имена переменных, которые надо подставить:

In [1]: ip = '10.1.1.1' In [2]: mask = 24 In [3]: f"IP: , mask: " Out[3]: 'IP: 10.1.1.1, mask: 24' Аналогичный результат с format можно получить так: ``"IP: , mask: ".format(ip=ip, mask=mask)``.

Очень важное отличие f-строк от format: f-строки — это выражение, которое выполняется, а не просто строка. То есть, в случае с ipython, как только мы написали выражение и нажали Enter, оно выполнилось и вместо выражений и подставились значения переменных.

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

In [1]: f"IP: , mask: " --------------------------------------------------------------------------- NameError Traceback (most recent call last) in () ----> 1 f"IP: , mask: " NameError: name 'ip' is not defined

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

In [5]: first_name = 'William' In [6]: second_name = 'Shakespeare' In [7]: f" " Out[7]: 'WILLIAM SHAKESPEARE'

python_17_ciscomaster.ru.jpg

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

Объединение литералов строк

В Python есть очень удобная функциональность — объединение литералов строк.

In [1]: s = ('Test' 'String') In [2]: s Out[2]: 'TestString' In [3]: s = 'Test' 'String' In [4]: s Out[4]: 'TestString'

Можно даже переносить составляющие строки на разные строки, но только если они в скобках:

In [5]: s = ('Test' . 'String') In [6]: s Out[6]: 'TestString'

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

regex = ('(\S+) +(\S+) +' # interface and IP '\w+ +\w+ +' '(up|down|administratively down) +' # Status '(\w+)') # Protocol

Также этим приемом удобно пользоваться, когда надо написать длинное сообщение:

In [7]: message = ('При выполнении команды "<>" ' . 'возникла такая ошибка "<>".\n' . 'Исключить эту команду из списка? [y/n]') In [8]: message Out[8]: 'При выполнении команды "<>" возникла такая ошибка "<>".\nИсключить эту команду из списка? [y/n]'

Список (List)

Список в Python это:
— Последовательность элементов, разделенных между собой запятой и заключенных в квадратные скобки
— Изменяемый упорядоченный тип данных

In [1]: list1 = [10,20,30,77] In [2]: list2 = ['one', 'dog', 'seven'] In [3]: list3 = [1, 20, 4.0, 'word']

Создание списка с помощью литерала:

vlans = [10, 20, 30, 50]

Создание списка с помощью функции list():

In [50]: list1 = list('router') In [51]: print (list1) ['r', 'o', 'u', 't', 'e', 'r']

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

In [52]: list3 = [1, 20, 4.0, 'word'] In [53]: list3[1] Out[53]: 20 In [54]: list3[1::] Out[54]: [20, 4.0, 'word'] In [55]: list3[-1] Out[55]: 'word' In [56]: list3[::-1] Out[56]: ['word', 4.0, 20, 1]

Перевернуть список наоборот можно и с помощью метода reverse():

In [63]: vlans = ['10', '15', '20', '30', '100-200'] In [64]: vlans.reverse() In [65]: vlans Out[65]: ['100-200', '30', '20', '15', '10']

Так как списки изменяемые, элементы списка можно менять:

In [66]: list3 Out[66]: [1, 20, 4.0, 'word'] In [67]: list3[0] = 'test' In [68]: list3 Out[68]: ['test', 20, 4.0, 'word']

Можно создавать и список списков. И, как и в обычном списке, можно обращаться к элементам во вложенных списках:

In [69]: interfaces = [['FastEthernet0/0', '15.0.15.1', 'YES', 'manual', 'up', 'up'], . ['FastEthernet0/1', '10.0.1.1', 'YES', 'manual', 'up', 'up'], . ['FastEthernet0/2', '10.0.2.1', 'YES', 'manual', 'up', 'down']] In [70]: interfaces[0][0] Out[70]: 'FastEthernet0/0' In [71]: interfaces[2][0] Out[71]: 'FastEthernet0/2' In [72]: interfaces[2][1] Out[72]: '10.0.2.1'

Функция len возвращает количество элементов в списке:

In [73]: items = [1, 2, 3] In [74]: len(items) Out[74]: 3

А функция sorted сортирует элементы списка по возрастанию и возвращает новый список с отсортированными элементами:

In [75]: names = ['John', 'Michael', 'Antony'] In [76]: sorted(names) Out[76]: ['Antony', 'John', 'Michael']

Полезные методы для работы со списками

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

join

Метод join собирает список строк в одну строку с разделителем, который указан перед join:

In [16]: vlans = ['10', '20', '30'] In [17]: ','.join(vlans) Out[17]: '10,20,30'

append

Метод append добавляет в конец списка указанный элемент:

In [18]: vlans = ['10', '20', '30', '100-200'] In [19]: vlans.append('300') In [20]: vlans Out[20]: ['10', '20', '30', '100-200', '300']

extend

Если нужно объединить два списка, то можно использовать два способа: метод extend и операцию сложения.
У этих способов есть важное отличие — extend меняет список, к которому применен метод, а суммирование возвращает новый список, который состоит из двух.

In [21]: vlans = ['10', '20', '30', '100-200'] In [22]: vlans2 = ['300', '400', '500'] In [23]: vlans.extend(vlans2) In [24]: vlans Out[24]: ['10', '20', '30', '100-200', '300', '400', '500']
In [27]: vlans = ['10', '20', '30', '100-200'] In [28]: vlans2 = ['300', '400', '500'] In [29]: vlans + vlans2 Out[29]: ['10', '20', '30', '100-200', '300', '400', '500']

результат суммирования можно присвоить в переменную.

Метод pop удаляет элемент, который соответствует указанному номеру. Но, что важно, при этом метод возвращает этот элемент:

In [28]: vlans = ['10', '20', '30', '100-200'] In [29]: vlans.pop(-1) Out[29]: '100-200' In [30]: vlans Out[30]: ['10', '20', '30']

Без указания номера удаляется последний элемент списка.

remove

Метод remove удаляет указанный элемент.
remove() не возвращает удаленный элемент:

In [31]: vlans = ['10', '20', '30', '100-200'] In [32]: vlans.remove('20') In [33]: vlans Out[33]: ['10', '30', '100-200']

В методе remove надо указывать сам элемент, который надо удалить, а не его номер в списке. Если указать номер элемента, возникнет ошибка

index

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

In [35]: vlans = ['10', '20', '30', '100-200'] In [36]: vlans.index('30') Out[36]: 2

insert

Метод insert позволяет вставить элемент на определенное место в списке:

In [37]: vlans = ['10', '20', '30', '100-200'] In [38]: vlans.insert(1, '15') In [39]: vlans Out[39]: ['10', '15', '20', '30', '100-200']

sort

Метод sort сортирует список на месте:

In [40]: vlans = [1, 50, 10, 15] In [41]: vlans.sort() In [42]: vlans Out[42]: [1, 10, 15, 50]

Словарь (Dictionary)

Словари — это изменяемый упорядоченный тип данных:

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

london =

Можно записывать и так:

london = < 'id': 1, 'name': 'London', 'it_vlan': 320, 'user_vlan': 1010, 'mngmt_vlan': 99, 'to_name': None, 'to_id': None, 'port': 'G1/0/11' >

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

In [80]: london = In [81]: print(london)

В словаре в качестве значения можно использовать словарь:

london_co = < 'r1': < 'hostname': 'london_r1', 'location': '21 New Globe Walk', 'vendor': 'Cisco', 'model': '4451', 'ios': '15.4', 'ip': '10.255.0.1' >, 'r2': < 'hostname': 'london_r2', 'location': '21 New Globe Walk', 'vendor': 'Cisco', 'model': '4451', 'ios': '15.4', 'ip': '10.255.0.2' >, 'sw1': < 'hostname': 'london_sw1', 'location': '21 New Globe Walk', 'vendor': 'Cisco', 'model': '3850', 'ios': '3.6.XE', 'ip': '10.255.0.101' >>

Получить значения из вложенного словаря можно так:

In [83]: london_co['r1']['ios'] Out[83]: '15.4'

Функция sorted сортирует ключи словаря по возрастанию и возвращает новый список с отсортированными ключами:

In [84]: london = In [85]: sorted(london) Out[85]: ['location', 'name', 'vendor']

Полезные методы для работы со словарями

clear

Метод clear позволяет очистить словарь:

In [1]: london = In [2]: london.clear() In [3]: london Out[3]: <>

copy

Метод copy позволяет создать полную копию словаря.

Если указать, что один словарь равен другому:

In [4]: london = In [5]: london2 = london In [6]: id(london) Out[6]: 25489072 In [7]: id(london2) Out[7]: 25489072 In [8]: london['vendor'] = 'Juniper' In [9]: london2['vendor'] Out[9]: 'Juniper'

В этом случае london2 это еще одно имя, которое ссылается на словарь. И при изменениях словаря london меняется и словарь london2, так как это ссылки на один и тот же объект.
Поэтому, если нужно сделать копию словаря, надо использовать метод copy():

In [10]: london = In [11]: london2 = london.copy() In [12]: id(london) Out[12]: 25524512 In [13]: id(london2) Out[13]: 25563296 In [14]: london['vendor'] = 'Juniper' In [15]: london2['vendor'] Out[15]: 'Cisco'

Если при обращении к словарю указывается ключ, которого нет в словаре, возникает ошибка:

In [16]: london = In [17]: london['ios'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) in () ----> 1 london['ios'] KeyError: 'ios'

Метод get запрашивает ключ, и если его нет, вместо ошибки возвращает None.

In [18]: london = In [19]: print(london.get('ios')) None

Метод get() позволяет также указывать другое значение вместо None:

In [20]: print(london.get('ios', 'Ooops')) Ooops

setdefault

Метод setdefault ищет ключ, и если его нет, вместо ошибки создает ключ со значением None.

In [21]: london = In [22]: ios = london.setdefault('ios') In [23]: print(ios) None In [24]: london Out[24]:

Если ключ есть, setdefault возвращает значение, которое ему соответствует:

In [25]: london.setdefault('name') Out[25]: 'London1'

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

In [26]: model = london.setdefault('model', 'Cisco3580') In [27]: print(model) Cisco3580 In [28]: london Out[28]:

keys, values, items

Методы keys, values, items:

In [24]: london = In [25]: london.keys() Out[25]: dict_keys(['name', 'location', 'vendor']) In [26]: london.values() Out[26]: dict_values(['London1', 'London Str', 'Cisco']) In [27]: london.items() Out[27]: dict_items([('name', 'London1'), ('location', 'London Str'), ('vendor', 'Cisco')])

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

Очень важная особенность view заключается в том, что они меняются вместе с изменением словаря. И фактически они лишь дают способ посмотреть на соответствующие объекты, но не создают их копию.

На примере метода keys:

In [28]: london = In [29]: keys = london.keys() In [30]: print(keys) dict_keys(['name', 'location', 'vendor'])

Сейчас переменной keys соответствует view dict_keys, в котором три ключа: name, location и vendor.

Если добавить в словарь еще одну пару ключ-значение, объект keys тоже поменяется:

In [31]: london['ip'] = '10.1.1.1' In [32]: keys Out[32]: dict_keys(['name', 'location', 'vendor', 'ip'])

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

In [33]: list_keys = list(london.keys()) In [34]: list_keys Out[34]: ['name', 'location', 'vendor', 'ip']

Удалить ключ и значение:

In [35]: london = In [36]: del london['name'] In [37]: london Out[37]:

update

Метод update позволяет добавлять в словарь содержимое другого словаря:

In [38]: r1 = In [39]: r1.update() In [40]: r1 Out[40]:

Аналогичным образом можно обновить значения:

In [41]: r1.update() In [42]: r1 Out[42]:

Кортеж (Tuple)

Кортеж в Python это:

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

Кортеж — это список, который нельзя изменить. То есть, в кортеже есть только права на чтение. Это может быть защитой от случайных изменений.

Кортеж из одного элемента (обратите внимание на запятую):

In [87]: tuple2 = ('password',) In [88]: tuple2 Out[88]: ('password',)

Кортеж из списка:

In [89]: list_keys = ['hostname', 'location', 'vendor', 'model', 'ios', 'ip'] In [90]: tuple_keys = tuple(list_keys) In [91]: tuple_keys Out[91]: ('hostname', 'location', 'vendor', 'model', 'ios', 'ip')

К объектам в кортеже можно обращаться, как и к объектам списка, по порядковому номеру:

In [93]: tuple_keys[0] Out[93]: 'hostname'

Но так как кортеж неизменяем, присвоить новое значение нельзя.

Функция sorted сортирует элементы кортежа по возрастанию и возвращает новый список с отсортированными элементами:

In [94]: tuple_keys Out[94]: ('hostname', 'location', 'vendor', 'model', 'ios', 'ip') In [95]: sorted(tuple_keys) Out[95]: ['hostname', 'ios', 'ip', 'location', 'model', 'vendor']

Множество (Set)

Множество — это изменяемый неупорядоченный тип данных. В множестве всегда содержатся только уникальные элементы.

Множество в Python — это последовательность элементов, которые разделены между собой запятой и заключены в фигурные скобки.

С помощью множества можно легко убрать повторяющиеся элементы:

In [1]: vlans = [10, 20, 30, 40, 100, 10] In [2]: set(vlans) Out[2]: In [3]: set1 = set(vlans) In [4]: print(set1)

Булевы значения

Булевы значения в Python это две константы True и False.

В Python истинными и ложными значениями считаются не только True и False.

  • истинное значение:
    — любое ненулевое число
    — любая непустая строка
    — любой непустой объект
  • ложное значение:
    — 0
    — None
    — пустая строка
    — пустой объект

Для проверки булевого значения объекта, можно воспользоваться bool:

In [1]: vlans = [10, 20, 30, 40, 100, 10] In [2]: set(vlans) Out[2]: In [3]: set1 = set(vlans) In [4]: print(set1) In [5]: items = [1, 2, 3] In [6]: empty_list = [] In [7]: bool(empty_list) Out[7]: False In [8]: bool(items) Out[8]: True In [9]: bool(0) Out[9]: False In [10]: bool(1) Out[10]: True

Преобразование типов

В Python есть несколько полезных встроенных функций, которые позволяют преобразовать данные из одного типа в другой.

In [11]: int("10") Out[11]: 10

С помощью функции int можно преобразовать и число в двоичной записи в десятичную (двоичная запись должна быть в виде строки)

In [12]: int("11111111", 2) Out[12]: 255
In [15]: hex(10) Out[15]: '0xa'
In [16]: list("string") Out[16]: ['s', 't', 'r', 'i', 'n', 'g'] In [17]: list((1, 2, 3, 4)) Out[17]: [1, 2, 3, 4]
In [20]: set([1, 2, 3, 3, 4, 4, 4, 4]) Out[20]: In [21]: set((1, 2, 3, 3, 4, 4, 4, 4)) Out[21]: In [22]: set("string string") Out[22]:
In [23]: tuple([1, 2, 3, 4]) Out[23]: (1, 2, 3, 4) In [24]: tuple() Out[24]: (1, 2, 3, 4) In [25]: tuple("string") Out[25]: ('s', 't', 'r', 'i', 'n', 'g')
In [26]: str(10) Out[26]: '10'

Проверка типов

При преобразовании типов данных могут возникнуть ошибки такого рода:

In [28]: int('a') --------------------------------------------------------------------------- ValueError Traceback (most recent call last) in ----> 1 int('a') ValueError: invalid literal for int() with base 10: 'a'

Чтобы избежать ошибок, было бы хорошо иметь возможность проверить, с чем мы работаем.

    isdigit
    чтобы проверить, состоит ли строка из одних цифр, можно использовать метод isdigit

In [29]: "a".isdigit() Out[29]: False In [30]: "10".isdigit() Out[30]: True
In [31]: "a".isalpha() Out[31]: True In [32]: "a100".isalpha() Out[32]: False
In [33]: "a".isalnum() Out[33]: True In [34]: "a10".isalnum() Out[34]: True
In [35]: type("string") Out[35]: str In [36]: type("10") Out[36]: str In [37]: type(10) Out[37]: int In [38]: type((1,2,3)) Out[38]: tuple In [39]: type((1,2,3)) == tuple Out[39]: True

Вызов методов цепочкой

Часто с данными надо выполнить несколько операций, например:

In [40]: line = "switchport trunk allowed vlan 10,20,30" In [41]: words = line.split() In [42]: words Out[42]: ['switchport', 'trunk', 'allowed', 'vlan', '10,20,30'] In [43]: vlans_str = words[-1] In [44]: vlans_str Out[44]: '10,20,30' In [45]: vlans = vlans_str.split(",") In [46]: vlans Out[46]: ['10', '20', '30']
line = "switchport trunk allowed vlan 10,20,30" words = line.split() vlans_str = words[-1] vlans = vlans_str.split(",") print(vlans)

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

line = "switchport trunk allowed vlan 10,20,30" vlans = line.split()[-1].split(",") print(vlans)

Главный нюанс при написании таких цепочек предыдущий метод/действие должен возвращать то, что ждет следующий метод/дествие. И обязательно чтобы что-то возвращалось, иначе будет ошибка.

Основы сортировки данных

При сортировке данных типа списка списков или списка кортежей, sorted сортирует по первому элементу вложенных списков (кортежей), а если первый элемент одинаковый, по второму:

In [47]: data = [[1, 100, 1000], [2, 2, 2], [1, 2, 3], [4, 100, 3]] In [48]: sorted(data) Out[48]: [[1, 2, 3], [1, 100, 1000], [2, 2, 2], [4, 100, 3]]

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

In [51]: vlans = ['1', '30', '11', '3', '10', '20', '30', '100'] In [52]: sorted(vlans) Out[52]: ['1', '10', '100', '11', '20', '3', '30', '30']

Чтобы сортировка была «правильной» надо преобразовать вланы в числа.

Задания

  1. Используя подготовленную строку nat, получить новую строку, в которой в имени интерфейса вместо FastEthernet написано GigabitEthernet. Полученную новую строку вывести на стандартный поток вывода (stdout) с помощью print.
    nat = «ip nat inside source list ACL interface FastEthernet0/1 overload» Решение
line = "ip nat inside source list ACL interface FastEthernet0/1 overload" words = line.split() words[7] = 'GigabitEthernet' line2 = words[0] + ' ' + words[1] + ' ' + words[2] + ' ' + words[3] + ' ' + words[4] + ' ' + words[5] + ' ' + words[6] + ' ' + words[7] + ' ' + words[8] print (line2)
line = "XXXX:XXXX:XXXX" words = line.split(':') line2 = words[0] + '.' + words[1] + '.' + words[2] print (line2)
config = "switchport trunk allowed vlan 1,3,10,20,30,100" words = config.split() vlans_str = words[-1] result = vlans_str.split(",") print(result)
vlans = [10, 20, 30, 1, 2, 100, 10, 30, 3, 4, 10] vlans2 = set(vlans) result = list(vlans2) print(result)
command1 = "switchport trunk allowed vlan 1,2,3,5,8" command2 = "switchport trunk allowed vlan 1,3,8,9" words1 = command1.split() words2 = command2.split() vlans_str1 = words1[-1] vlans_str2 = words2[-1] vlans1 = vlans_str1.split(",") vlans2 = vlans_str2.split(",") result = list(set(vlans1) & set(vlans2)) print(result)
ospf_route = " 10.0.24.0/24 [110/41] via 10.0.13.3, 3d18h, FastEthernet0/0" words = ospf_route.split() print ('Prefix\t',words[0]) print ('AD/Metric\t',words[1]) print ('Next-Hop\t',words[3][:-1]) print ('Last update\t',words[4][:-1]) print ('Outbound Interface\t',words[5])

python_18_ciscomaster.ru.jpgРешение с использованием форматирования, а также метода strip:
python_20_ciscomaster.ru.jpgpython_19_ciscomaster.ru.jpg
Преобразовать MAC-адрес в строке mac в двоичную строку такого вида: „101010101010101010111011101110111100110011001100“
Полученную новую строку вывести на стандартный поток вывода (stdout) с помощью print.
mac = «AAAA:BBBB:CCCC» Решение

mac = "D45D:6401:01BC" mac_hex = mac.split(":") mac_string = mac_hex[0] + mac_hex[1] +mac_hex[2] int = int(mac_string, 16) result = bin(int)

python_21_ciscomaster.ru.jpg

Преобразовать IP-адрес в переменной ip в двоичный формат и вывести на стандартный поток вывода вывод столбцами, таким образом: первой строкой должны идти десятичные значения байтов
второй строкой двоичные значения
Вывод должен быть упорядочен также, как в примере: столбцами
ширина столбца 10 символов (в двоичном формате надо добавить два пробела между столбцами для разделения октетов между собой)
Пример вывода для адреса 10.1.1.1:

10 1 1 1 00001010 00000001 00000001 00000001

ip = «192.168.3.1» Решение без форматирования:

ip = "192.168.3.1" ip_split = ip.split(".") print(ip_split[0],' '*10,ip_split[1],' '*10,ip_split[2],' '*10,ip_split[3]) print(bin(int(ip_split[0])),' '*2,bin(int(ip_split[1])),' '*2,bin(int(ip_split[2])),' '*2,bin(int(ip_split[3])))

python_22_ciscomaster.ru.jpgРешение с форматированием:
python_23_ciscomaster.ru.jpgpython_24_ciscomaster.ru_0.jpg

Задания

  1. Задание 6.1
    Список mac содержит MAC-адреса в формате XXXX:XXXX:XXXX. Однако, в оборудовании cisco MAC-адреса используются в формате XXXX.XXXX.XXXX. Написать код, который преобразует MAC-адреса в формат cisco и добавляет их в новый список result. Полученный список result вывести на стандартный поток вывода (stdout) с помощью print. Ограничение: Все задания надо выполнять используя только пройденные темы.
mac = ["aabb:cc80:7000", "aabb:dd80:7340", "aabb:ee80:7000", "aabb:ff80:7000"]

Решение

mac = ["aabb:cc80:7000", "aabb:dd80:7340", "aabb:ee80:7000", "aabb:ff80:7000"] result = [] for line in mac: words = line.split(':') line2 = words[0] + '.' + words[1] + '.' + words[2] result.append(line2) print (result)

Более правильное решение

mac = ["aabb:cc80:7000", "aabb:dd80:7340", "aabb:ee80:7000", "aabb:ff80:7000"] result = [] for line in mac: result.append(line.replace(":", ".")) print(result)

Какие математические операторы можно применять для двух объектов формата str

Переменные предназначены для хранения данных. Название переменной в Python должно начинаться с алфавитного символа или со знака подчеркивания и может содержать алфавитно-цифровые символы и знак подчеркивания. И кроме того, название переменной не должно совпадать с названием ключевых слов языка Python. Ключевых слов не так много, их легко запомнить:

False await else import pass None break except in raise True class finally is return and continue for lambda try as def from nonlocal while assert del global not with async elif if or yield

Например, создадим переменную:

name = "Tom"

Здесь определена переменная name , которая хранит строку «Tom».

В пайтоне применяется два типа наименования переменных: camel case и underscore notation .

Camel case подразумевает, что каждое новое подслово в наименовании переменной начинается с большой буквы. Например:

userName = "Tom"

Underscore notation подразумевает, что подслова в наименовании переменной разделяются знаком подчеркивания. Например:

user_name = "Tom"

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

# две разные переменные name = "Tom" Name = "Tom"

Определив переменную, мы можем использовать в программе. Например, попытаться вывести ее содержимое на консоль с помощью встроенной функции print :

name = "Tom" # определение переменной name print(name) # вывод значения переменной name на консоль

Например, определение и применение переменной в среде PyCharm:

Переменные в Python

Отличительной особенностью переменной является то, что мы можем менять ее значение в течение работы программы:

name = "Tom" # переменной name равна "Tom" print(name) # выводит: Tom name = "Bob" # меняем значение на "Bob" print(name) # выводит: Bob

Типы данных

Переменная хранит данные одного из типов данных. В Python существует множество различных типов данных. В данном случае рассмотрим только самые базовые типы: bool , int , float , complex и str .

Логические значения

Тип bool представляет два логических значения: True (верно, истина) или False (неверно, ложь). Значение True служит для того, чтобы показать, что что-то истинно. Тогда как значение False , наоборот, показывает, что что-то ложно. Пример переменных данного типа:

isMarried = False print(isMarried) # False isAlive = True print(isAlive) # True

Целые числа

Тип int представляет целое число, например, 1, 4, 8, 50. Пример

age = 21 print("Возраст:", age) # Возраст: 21 count = 15 print("Количество:", count) # Количество: 15

По умолчанию стандартные числа расцениваются как числа в десятичной системе. Но Python также поддерживает числа в двоичной, восьмеричной и шестнадцатеричной системах.

Для указания, что число представляет двоичную систему, перед числом ставится префикс 0b :

a = 0b11 b = 0b1011 c = 0b100001 print(a) # 3 в десятичной системе print(b) # 11 в десятичной системе print(c) # 33 в десятичной системе

Для указания, что число представляет восьмеричную систему, перед числом ставится префикс 0o :

a = 0o7 b = 0o11 c = 0o17 print(a) # 7 в десятичной системе print(b) # 9 в десятичной системе print(c) # 15 в десятичной системе

Для указания, что число представляет шестнадцатеричную систему, перед числом ставится префикс 0x :

a = 0x0A b = 0xFF c = 0xA1 print(a) # 10 в десятичной системе print(b) # 255 в десятичной системе print(c) # 161 в десятичной системе

Стоит отметить, что в какой-бы системе мы не передали число в функцию print для вывода на консоль, оно по умолчанию будет выводиться в десятичной системе.

Дробные числа

Тип float представляет число с плавающей точкой, например, 1.2 или 34.76. В качесте разделителя целой и дробной частей используется точка.

height = 1.68 pi = 3.14 weight = 68. print(height) # 1.68 print(pi) # 3.14 print(weight) # 68.0

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

x = 3.9e3 print(x) # 3900.0 x = 3.9e-3 print(x) # 0.0039

Число float может иметь только 18 значимых символов. Так, в данном случае используются только два символа — 3.9. И если число слишком велико или слишком мало, то мы можем записывать число в подобной нотации, используя экспоненту. Число после экспоненты указывает степень числа 10, на которое надо умножить основное число — 3.9.

Комплексные числа

Тип complex представляет комплексные числа в формате вещественная_часть+мнимая_часть j — после мнимой части указывается суффикс j

complexNumber = 1+2j print(complexNumber) # (1+2j)

Строки

Тип str представляет строки. Строка представляет последовательность символов, заключенную в одинарные или двойные кавычки, например «hello» и ‘hello’. В Python 3.x строки представляют набор символов в кодировке Unicode

message = "Hello World!" print(message) # Hello World! name = 'Tom' print(name) # Tom

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

text = ("Laudate omnes gentes laudate " "Magnificat in secula ") print(text)

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

''' Это комментарий ''' text = '''Laudate omnes gentes laudate Magnificat in secula Et anima mea laudate Magnificat in secula ''' print(text)

При использовани тройных одинарных кавычек не стоит путать их с комментариями: если текст в тройных одинарных кавычках присваивается переменной, то это строка, а не комментарий.

Управляющие последовательности в строке

Строка может содержать ряд специальных символов — управляющих последовательностей. Некоторые из них:

  • \\ : позволяет добавить внутрь строки слеш
  • \’ : позволяет добавить внутрь строки одинарную кавычку
  • \» : позволяет добавить внутрь строки двойную кавычку
  • \n : осуществляет переход на новую строку
  • \t : добавляет табуляцию (4 отступа)

Применим несколько последовательностей:

text = "Message:\n\"Hello World\"" print(text)

Консольный вывод программы:

Message: "Hello World"

Хотя подобные последовательности могут нам помочь в некоторых делах, например, поместить в строку кавычку, сделать табуляцию, перенос на другую строку. Но они также могут и мешать. Например:

path = "C:\python\name.txt" print(path)

Здесь переменная path содержит некоторый путь к файлу. Однако внутри строки встречаются символы «\n», которые будут интерпретированы как управляющая последовательность. Так, мы получим следующий консольный вывод:

C:\python ame.txt

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

path = r"C:\python\name.txt" print(path)
Вставка значений в строку

Python позволяет встравивать в строку значения других переменных. Для этого внутри строки переменные размещаются в фигурных скобках <>, а перед всей строкой ставится символ f :

userName = "Tom" userAge = 37 user = f"name: age: " print(user) # name: Tom age: 37

В данном случае на место будет вставляться значение переменной userName. Аналогично на вместо будет вставляться значение переменной userAge.

Динамическая типизация

Python является языком с динамической типизацией. А это значит, что переменная не привязана жестко к определенному типу.

Тип переменной определяется исходя из значения, которое ей присвоено. Так, при присвоении строки в двойных или одинарных кавычках переменная имеет тип str . При присвоении целого числа Python автоматически определяет тип переменной как int . Чтобы определить переменную как объект float, ей присваивается дробное число, в котором разделителем целой и дробной части является точка.

При этом в процессе работы программы мы можем изменить тип переменной, присвоив ей значение другого типа:

userId = "abc" # тип str print(userId) userId = 234 # тип int print(userId)

С помощью встроенной функции type() динамически можно узнать текущий тип переменной:

userId = «abc» # тип str print(type(userId)) # userId = 234 # тип int print(type(userId)) #

3.1. Теория¶

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

3.1.1. Понятие типа данных и переменной¶

Тип данных (англ. Data type) — характеристика, определяющая:

  • множество допустимых значений, которые могут принимать данные, принадлежащие к этому типу (например, объект типа Целое число может принимать только целочисленные значения в определенном диапазоне);
  • набор операций, которые можно осуществлять над данными, принадлежащими к этому типу (например, объекты типа Целое число умеют складываться, умножаться и т.д.).

Все типы в Python являются объектами (в отличие, например, от C++). При создании объекта вызывается специальная функция — конструктор.

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

Для имен переменных используется змеиный_регистр (англ. snake_case): например, my_variable или i .

Информативные имена переменных.

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

Например, переменную, хранящую данные о скорости можно назвать speed , а не sk ; значение баланса телефона клиента — balance , а не b и т.д. «Привычные» со школы короткие имена следует использовать там, где они либо подходят по смыслу (например, a , b , c в роли коэффициентов квадратного уравнения), либо используются временно (например, счетчик i в циклической конструкции).

3.1.1.1. Классификация типов данных¶

В Python встроенные типы данных подразделяются на 2 группы:

  1. Числа (целое, вещественное).
  2. Логический тип.
  3. NoneType.
  1. Последовательности: строка, список, кортеж, числовой диапазон.
  2. Множества.
  3. Отображения: словарь.

Кроме того, все объекты в Python относятся к одной из 2-х категорий:

  1. Мутирующие (англ. Mutable): содержимое объекта можно изменить после создания (например, список);
  2. Немутирующие (англ. Immutable): содержимое объекта нельзя изменить после создания (например, строка или число).

Также часто используется терминология «изменяемые» и «неизменяемые» типы соответственно.

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

3.1.1.2. Оператор присваивания¶

Для связывания (и при необходимости предварительного создания) объекта и переменной используется оператор присваивания = .

Присваивание выполняется «справа налево» и подразумевает шаги:

    если справа от оператора находится литерал (например, строка или число) в операнд слева записывается ссылка, которая указывает на объект в памяти, хранящий значение литерала:

a = 100 # Создание объекта 100 и запись ссылки на него в переменную 'a' 
a = 100 b = a # В переменную 'b' копируется ссылка из 'a' - # они будут указывать на один и тот же объект 

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

В связи с этим целесообразнее в Python в качестве метафоры рассматривать переменные как стикеры (этикетки), цепляемые к данным, а не ящики (Рисунок 3.1.1) и говорить, что «переменная присвоена объекту», а не привычное «переменной присвоен объект».

_images/03_01_01.png

Рисунок 3.1.1 — Переменные в Python — стикеры, а не ящики 3 ¶

Пример использования оператора присваивания приведен в Листинге 3.1.1.

Листинг 3.1.1 — Оператор присваивания в Python ¶

# Выражение присваивания в Python может быть записано несколькими способами в # зависимости от содержимого левой части (l-значение) и правой части (r-значение). # 1. Простое присваивание использует одно l-значение и одно r-значение. # # Объект 5 целого типа связывается с переменной 'a' >>> a = 5 >>> a 5 # 2. Сокращенная запись присваивания часто применяется когда нужно обновить # значение переменной по отношению к текущему значению. # Сокращенная запись образуется для всех операторов одинаково, например # '*=' для умножения и т.д. # # Увеличиваем значение связанного целого объекта 'a' на 1, эквивалентно a = a + 1 >>> a += 1 >>> a 6 # 3. Также возможно параллельное присваивание, где выражение присваивания # содержит больше одного l- и r-значений. # # Связывание значений 1, "aaa", 3 с переменными 'x', 'y', 'z' соответственно >>> x, y, z = 1, "aaa", 3 >>> x, y, z (1, 'aaa', 3) # Возможно также не совпадения количества значения l- и r-значений, # данный случай рекомендуется рассмотреть самостоятельно. # 4. Оператор присваивание выполняется справа налево, поэтому также можно # образовывать цепочки присваивания. # # 0 связывается с переменной 'y', а затем и с переменной 'x' >>> x = y = 0 >>> x, y (0, 0) 

Инициализация переменной перед использованием

Переменная должна быть проинициализирована (ссылаться на данные) перед использованием в выражении. Например, код a = b + 2 или b += 1 , вызовет ошибку, если идентификатор b не был предварительно определен.

Присваивание и побочный эффект

Присваивание, меняя значение переменной, изменяет состояние программы — т.е. имеет побочный эффект. После выполнения присваивания, например x += 1 , весь дальнейший код программы будет иметь дело с новым, измененным значением 1.

3.1.1.3. Управление памятью и сборщик мусора¶

Создание объекта любого типа подразумевает выделение памяти для размещения данных об этом объекте. Когда объект больше не нужен — его необходимо удалить, очистив занимаемую память. Python — язык с встроенным менеджером управления памятью и выполняет данные операции автоматически за счет наличия сборщика мусора (англ. Garbage Collection, GC).

Сборка мусора — технология, позволяющая, с одной стороны, упростить программирование, избавив программиста от необходимости вручную удалять объекты, созданные в динамической памяти, с другой — устранить ошибки, вызванные неправильным ручным управлением памятью. Алгоритм, используемый сборщиком мусора называется подсчетом ссылок (англ. Reference Counting). Python хранит журнал ссылок на каждый объект и автоматически уничтожает объект, как только на него больше нет ссылок (Рисунок 3.1.2).

Рисунок 3.1.2 — Примерная схема работы сборщика мусора ¶

Время между созданием и уничтожением объекта — его жизненный цикл.

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

3.1.2. Скалярные типы¶

3.1.2.1. Числа¶

В Python существует 2 категории чисел: целые и вещественные (с плавающей точкой).

3.1.2.1.1. Целое число¶

Целые числа в Python представлены типом int .

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

Листинг 3.1.2 — Пример литералов целых чисел ¶

>>> 15 # десятичное число 15 >>> 0b1111 # двоичное число 15 >>> 0o17 # восьмеричное число 15 >>> 0xF # шестнадцатиричное число 15 
3.1.2.1.2. Вещественное число¶

Python предоставляет три типа значений с плавающей точкой:

  • float (двойная точность)
  • complex (комплексные числа вида 3.5 + 5j );
  • decimal.Decimal (большая точность, по умолчанию 28 знаков после запятой).

Наиболее часто используемый тип float представляет числа с плавающей точкой двойной точности, диапазон значений которых зависит от компилятора, применявшегося для компиляции интерпретатора Python. Числа типа float записываются с десятичной точкой или в экспоненциальной форме записи (Листинг 3.1.3).

Листинг 3.1.3 — Пример литералов вещественных чисел ¶

>>> 5.7 # Точка - разделитель целой и дробной части 5.7 >>> 4. # Если дробной части нет, ее можно опустить 4.0 >>> -2.5 # Отрицательное вещественное число -2.5 >>> 8e-4 # Экспоненциальная форма записи 0.0008 >>> 0.1 + 0.2 # Проблема потери точности актуальна для вещественных чисел 0.30000000000000004 

Для чисел с плавающей точкой существует ряд нюансов:

  • в машинном представлении такие хранятся как двоичные числа. Это означает, что одни дробные значения могут быть представлены точно (такие как 0.5 ), а другие — только приблизительно (такие как 0.1 и 0.2 , например, их сумма будет равна не 0.3 , а 0.30000000000000004 );
  • для представления используется фиксированное число битов, поэтому существует ограничение на количество цифр в представлении таких чисел.

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

3.1.2.1.3. Операции над числами¶

Типовые операции, которые можно производить над числами ( int и float ), указаны в Листинге 3.1.4.

Для арифметических операций тип результата операции определяется типом аргументов. Если тип результата явно не предусмотрен при вычислении (например, округление до целых подразумевает получение результата типа int ), действуют следующие правила:

  • float : если хотя бы один аргумент имеет тип float ;
  • int : если все аргументы имеют тип int .

Листинг 3.1.4 — Операции над числами в Python ¶

# 1. Арифметические операции # Тип результата операции определяется типом аргументов # -х # Меняет знак х на обратный >>> x = 5 >>> -x -5 # х + у, х - у, х * у # Сложение, разность, произведение чисел х и у >>> 5 + 3 8 >>> 5 - 7 -2 >>> 5 * 3 15 # х / у # Делит х на у (результат типа float) >>> 5 / 3 1.6666666666666667 # x // y # Делит х на у нацело - усекает дробную часть (результат типа int) >>> 5 // 3 1 # х % у # Возвращает модуль (остаток) от деления х на у >>> 5 % 3 2 # x**y # Возводит х в степень у >>> 5**3 125 # abs(x) # Возвращает абсолютное значение х >>> abs(-5) 5 # round(x, n) # Возвращает значение x, округленное до n знаков после запятой; # тип результата зависит от n (int, если n равно 0, при этом его можно не указывать) >>> round(4/3, 2) 1.33 >>> round(4/3) 1 # 2. Равенство и сравнение # Результат логического типа # x == y, x != y # Проверка чисел на равенство/неравенство >>> 5 == 4 False >>> 5 != 4 True # x > y, x < y, x >= y, x # Больше, меньше, больше или равно, меньше или равно >>> 5 > 4 True >>> 5  5 True # Возможно составление цепочек сравнений >>> 3  4  5 True 

3.1.2.2. Логический тип¶

Логический тип представлен типом bool :

и позволяет хранить 2 значения:

  • True (Истина / Да / 1);
  • False (Ложь / Нет / 0).

Операции, которые можно производить над объектами логического типа, указаны в Листинге 3.1.5.

Листинг 3.1.5 — Операции над объектами логического типа в Python ¶

>>> x = True >>> y = False >>> not x False >>> x and y False >>> x or y True # Python использует "ленивую" модель вычисления: если на каком-то # этапе результат выражения известен, оно не вычисляется до конца >>> (4 > 5) and (5 > 2) False 

Правила выполнения операций соответствует логическим таблицам истинности.

3.1.2.3. NoneType¶

В Python существует специальное значение None типа NoneType, обозначающее нейтральное или «нулевое» поведение. Присвоение такого значения ничем не отличается от других: a = None , обозначая, что идентификатор a задан, но ни с чем не связан.

Наиболее часто используется для защитного программирования — «если что-то не None, можно продолжать работу программы».

3.1.3. Коллекции¶

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

Коллекции — это группа типов данных, которые содержат в себе другие данные и поддерживают:

  • проверку на вхождения элементов in и not in ( True / False );
  • определение размера len() ;
  • возможность выполнения итераций (перемещения по элементам последовательности) — из-за этого коллекции также называются итерируемыми объектами (подробнее рассматриваются в Теме №4 ).

Среди коллекций выделяют 3 группы:

  • последовательности: строка, список, кортеж, числовой диапазон;
  • множества;
  • отображения: словарь.

3.1.3.1. Последовательности¶

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

Некоторые последовательности в Python в отличие от традиционных массивов (например, в Паскале или Си) могут хранить элементы различного типа (в том числе и коллекции различных видов).

В языке Python имеется пять встроенных типов последовательностей (Таблица 3.1.1).

Далее подробно рассматриваются объекты str , list , tuple и range .

3.1.3.1.1. Общие операции¶

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

Ниже используются следующие обозначения:

  • s и t : последовательности одного типа;
  • n , k , start , end , step : целые числа;
  • x : произвольный объект, отвечающий критериям соответствующего вызова функции.

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

Конкатенация («склеивание») s + t

Возвращает новый объект — «склейку» s и t .

Дублирование s * n n * s

Возвращает последовательность, повторяющуюся n раз.

Индексация и срезы

Получить доступ к отдельному элементу или группе элементов последовательности возможно с помощью оператора [] . Индексацию (получение отдельного элемента) можно считать частным случаем получения среза (слайсинга).

Оператор получения среза имеет три формы записи:

  • s[start] : индексация (с 0);
  • s[start:end] : срез [start; end) ;
  • s[start:end:step] : срез [start; end) c шагом step .

В ряде случаев целочисленные параметры start , end и step могут быть опущены. Элемент с индексом end не включается в результат при взятии срезов.

Минимальное и максимальное значения min ( s ) ¶ max ( s ) ¶

Возвращает минимальный и максимальный элементы последовательности s соответственно.

Проверка на вхождение x in s

Возвращает True , если x входит в последовательность s и False в противном случае.

Индекс (положение) элемента s.index(x[, start[, end]]) —> int

Возвращает первое вхождение элемента x в последовательность s (между индексами start и end , если они заданы).

Количество повторений s. count ( x ) ¶

Возвращает количество вхождений элементов x в последовательность s .

Сортировка sorted ( s , key = None , reverse = False ) ¶

Возвращает отсортированный объект в виде списка. Исходный объект при этом не изменяется.

  • key – функция сортировки (по умолчанию не учитывается, сортировка осуществляется поэлементно);
  • reverse – если равен True , сортировка осуществляется в обратном порядке.

В Листинге 3.1.6 приведен пример выполнения указанных операций на примере последовательности «Список». Выполнение срезов отдельно рассматривается на примере строк ниже.

Листинг 3.1.6 — Общие операции для последовательностей ¶

>>> s = [1, 2, 3] # Список из 3-х целых чисел >>> len(s) 3 >>> 1 in s True >>> 5 in s False >>> s += [5, 6] >>> s [1, 2, 3, 5, 6] >>> s *= 2 >>> s [1, 2, 3, 5, 6, 1, 2, 3, 5, 6] >>> min(s), max(s) (1, 6) >>> s.index(5) 3 >>> s.count(4) 0 >>> sorted(s) [1, 1, 2, 2, 3, 3, 5, 5, 6, 6] 
3.1.3.1.2. Строка¶

Строка ( str ) — это упорядоченная неизменяемая последовательность символов Юникода.

class str ( object = » ) ¶ class str ( object = b» , encoding = ‘utf-8’ , errors = ‘strict’ )

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

Важным для строкового типа является понятие кодировки символов, что в частности, влияет на правила сравнения строк. По умолчанию Python хранит строки в кодировке UTF-8.

Если в строке необходимо использовать специальные символы (например, перенос или одноименные кавычки), можно воспользоваться механизмом экранирования символов, для чего используется специальный символ \ . В Таблице 3.1.2 приведены некоторые из экранированных последовательностей.

Таблица 3.1.2 — Экранированные последовательности в Python ¶

Символ «Перевод строки»

Пример создания строковых литералов приведен в Листинге 3.1.7, базовые операции — в Листинге 3.1.8.

Листинг 3.1.7 — Создание строк ¶

# Запись строковых литералов "Простой текст в кавычках" 'Текст в апострофах' """А это текст, который занимает 2 строки (в данном случае использовать три апострофа не рекомендуется)""" # Экранированные последовательности начинаются с символа \ "Текст, который содержит \"текст в кавычках\"" 'Текст, который содержит \'текст в апострофах\'' "Если внутри кавычки другого типа, можно не 'экранировать'" "Так в строке будет табуляция\tи\nперенос, а также обратный слеш \\" # "Отключить" экранирование можно указав, что строка является "сырой" r"Так в строке не будет табуляция\tи\nпереноса, но будет 2 обратных слеша \\" 

Листинг 3.1.8 — Операции над строковым типом ¶

# 1. Арифметические операции # Тип результата операции определяется типом аргументов # s1 + s2 # Соединяет строки s1 и s2 >>> "Py" + "thon" 'Python' # или просто написать рядом >>> "Py" "thon" 'Python' # s1 * n # Составляет строку из n повторений строки s1 >>> "па" * 2 'папа' # 2. Равенство и сравнение # Результат логического типа # # Операции сравнения выполняются посимвольно слева направо с учетом кодировки. # Ознакомиться с таблицей символов Юникода рекомендуется на ресурсе # http://unicode-table.com/. # s1 == s2, s1 != s2 # Проверка строк на равенство/неравенство >>> "текст1" == "текст2" False >>> "текст1" != "текст2" True # x > y, x < y, x >= y, x # Больше, меньше, больше или равно, меньше или равно >>> "текст1" > "текст2" False >>> "текст1"  "текст2" True # Возможно составление цепочек сравнений >>> "текст1"  "текст12"  "текст2" True # s1 in s2 # Проверка вхождения строки s1 в s2 >>> "p" in "Python" False 

Пример доступа к отдельному символу и получения срезов приведен в Листинге 3.1.9.

Листинг 3.1.9 — Индексация и срезы ¶

# Для индексации и получения срезов удобно пользоваться обозначениями ниже # # Индексация # +---+---+---+---+---+---+ # | P | y | t | h | o | n | # +---+---+---+---+---+---+ # 0 1 2 3 4 5 # -6 -5 -4 -3 -2 -1 # # Срезы # +---+---+---+---+---+---+ # | P | y | t | h | o | n | # +---+---+---+---+---+---+ # 0 1 2 3 4 5 6 # -6 -5 -4 -3 -2 -1 >>> s = "Python" >>> s[0] 'P' >>> s[3] 'h' >>> s[-1] # Последний символ 'n' >>> s[0:2] # Срез включает первые 2 символа 'Py' >>> s[2:-1] # С 3 по предпоследний символ 'tho' >>> s[0:-1:2] # С 1 по предпоследний символ через 2 'Pto' # Параметры [start] и [end] могут быть опущены # В таком случае срез берется с начала и до конца строки соответственно >>> s[:3] # Первые 3 символа 'Pyt' >>> s[3:] # С 3-го символа до конца 'hon' >>> 
3.1.3.1.2.1. Характерные операции¶

Строки поддерживают все общие операции для последовательностей и имеют ряд дополнительных методов.

Возвращает символ № i из таблицы Unicode.

Возвращает номер символа c из таблицы Unicode.

Пусть s — строка, на которой вызывается метод.

Возвращает копию строки s в верхнем регистре.

Возвращает копию строки s в нижнем регистре.

Возвращает копию строки с первым символом в верхнем регистре.

Возвращает копию строки, в которой первые символы каждого слова преобразованы в верхний регистр, а все остальные — в нижний регистр.

Возвращает число вхождений строки t в строку s (или в срез s[start:end] ).

Возвращает позицию самого первого (крайнего слева) вхождения подстроки t в строку s (или в срез s[start:end] ); если подстрока t не найдена, возвращается -1 .

Аналогично str.find() , но генерируется исключение ValueError , если подстрока не найдена.

Возвращает копию строки s , в которой каждое (но не более count , если этот аргумент определен) вхождение подстроки old замещается подстрокой new .

split ( sep = None , maxsplit = — 1 ) ¶

Возвращает список строк, разбитых по строке sep .

Возвращает строку-«склейку» элементов seq , используя s в качестве разделителя.

Пример использования строковых методов приведен в Листинге 3.1.10.

Листинг 3.1.10 — Использование строковых методов ¶

>>> s = "ЭТО просТо ТеКст" >>> ord(s[0]) 1069 >>> chr(1069) 'Э' >>> s.upper(), s.lower(), s.title(), s.capitalize() ('ЭТО ПРОСТО ТЕКСТ', 'это просто текст', 'Это Просто Текст', 'Это просто текст') >>> s.find("Т") 1 >>> s.replace("Т", "т") 'ЭтО просто теКст' >>> lst = s.split() >>> lst ['ЭТО', 'просТо', 'ТеКст'] >>> "-".join(lst) 'ЭТО-просТо-ТеКст' 
3.1.3.1.2.2. Форматирование строк¶

Строковый тип в Python содержит специальный метод str.format() , который позволяет удобно формировать строку из комбинации значений различного типа.

Пусть s — строка, на которой вызывается метод.

Возвращает отформатированную строку по заданному шаблону.

Строка s может содержать фигурные скобки <> (заполнители), указывающие, что их необходимо заменить на какое-либо значение. Заполнитель может содержать индекс или ключевое слово — в противном случае замена будет производится слева направо.

Пример использования метода str.format() приведен в Листинге 3.1.11.

Листинг 3.1.11 — Форматирование строк ¶

>>> age = 20 >>> name = "Максим" # 1. Без указания индексов подстановки >>> "Меня зовут <>, мне <> лет.".format(name, age) 'Меня зовут Максим, мне 20 лет.' # 2. Указание индексов подстановки (их можно и повторять!) >>> "Меня зовут , мне  лет.".format(name, age) 'Меня зовут Максим, мне 20 лет.' # 3. Именованные аргументы >>> "  ходит на  каждую пятницу".\ . format(subject="Мат. анализ", name="Иван") 'Иван ходит на Мат. анализ каждую пятницу' # 4. Интерполяция (f-string, начиная с Python 3.6) >>> f"name> ходит на subject> каждую пятницу" 'Иван ходит на Мат. анализ каждую пятницу' # 5. Модификаторы позволяют дополнительно указывать тип или формат выводимых данных # 5.1. Вывод вещественного числа с 2-мя знаками после запятой >>> "За 1 рубль дают $ ".format(1/70) 'За 1 рубль дают $0.01' # 5.2. Или вывод большого числа с "тысячными разделителями" >>> "Стоимость автомобиля:  руб.".format(5300500) 'Стоимость автомобиля: 5,300,500 руб.' 

Метод str.format обладает широкими возможностями. Дополнительно ознакомьтесь с официальной документацией по «мини-языку» форматирования.

3.1.3.1.3. Список¶

Список ( list ) — это упорядоченная изменяемая последовательность элементов.

  • может содержать элементы разного типа;
  • поддерживает операторы сравнения: при этом сравнивание производится поэлементно (и рекурсивно, при наличии вложенных элементов).

Создать список можно несколькими способами (Листинг 3.1.12).

Листинг 3.1.12 — Создание списка ¶

# 1. Пустой список создается с помощью пустых квадратных скобок или функции list() >>> [] [] >>> list() [] # 2. Инициализировать список элементами можно одним из следующих способов: >>> [1, "text", 2.0] [1, 'text', 2.0] >>> list("text") ['t', 'e', 'x', 't'] 
3.1.3.1.3.1. Характерные операции¶

Списки поддерживают все общие операции для последовательностей, и имеют ряд дополнительных методов.

Пусть lst — список, на котором вызывается метод.

Добавляет элемент x в конец списка lst .

extend ( m ) ¶ lst += m

Добавляет в конец списка lst все элементы коллекции m .

Вставляет элемент х в список lst в позицию i .

Удаляет из списка lst первый элемент со значением x .

Возвращает последний или i -й элемент, удаляя его из последовательности.

Удаляет из списка lst все элементы (очищает список).

sort ( lst , key = None , reverse = None ) ¶

Выполняет сортировку списка lst . Отличается от функции sorted() тем, что сортирует исходный объект, а не возвращает новый.

  • key – функция сортировки (по умолчанию не учитывается, сортировка осуществляется поэлементно);
  • reverse – если равен True , сортировка осуществляется в обратном порядке.

Переворачивает элементы списка lst .

Удаляет из списка lst элемент с индексом i (или несколько элементов, если задан индекс j ).

В Листинге 3.1.13 приведен пример использования методов списков.

Листинг 3.1.13 — Работа со списками ¶

# 1. Методы списка >>> a = [8, 7, 5.5, 1000, 3.50, 200] >>> a[0] = 7 >>> a [7, 7, 5.5, 1000, 3.50, 200] >>> a.index(7) 0 >>> a.count(7) 2 >>> a.insert(2, 1000) >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200] >>> a.append(5.5) >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5] >>> a += [0, 0] >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5, 0, 0] >>> b = a.pop() >>> b 0 >>> a [7, 7, 1000, 5.5, 1000, 3.5, 200, 5.5, 0] >>> a.sort() >>> a [0, 3.5, 5.5, 5.5, 7, 7, 200, 1000, 1000] >>> a.remove(1000) >>> a [0, 3.5, 5.5, 5.5, 7, 7, 200, 1000] >>> del a[2:4] >>> a [0, 3.5, 7, 7, 200, 1000] >>> a.reverse() >>> a [1000, 200, 7, 7, 3.5, 0] # 2. Сравнения и равенство # Простое сравнение >>> a = [1, 5, 10] >>> b = [1, 5, 10] >>> a == b True >>> b[0] = 5 >>> b [5, 5, 10] >>> a  b True # Вложенное сравнение >>> a[0] = [3, "aaa"] >>> b[0] = [3, "bb"] >>> a, b ([[3, 'aaa'], 5, 10], [[3, 'bb'], 5, 10]) >>> a  b True 
3.1.3.1.4. Кортеж¶

Кортеж ( tuple ) — это упорядоченная неизменяемая последовательность элементов.

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

Создать кортеж можно несколькими способами (Листинге 3.1.14).

Листинг 3.1.14 — Создание кортежа ¶

# 1. Пустой кортеж создается с помощью пустых круглых скобок или функции tuple() >>> () () >>> tuple() () # 2. Инициализировать кортеж элементами можно одним из следующих способов: >>> 1, (1,) >>> 1, 2, "text" (1, 2, 'text') >>> s = tuple("text") >>> s ('t', 'e', 'x', 't') >>> # 3. Т.к. структура является неизменяемой, изменение содержимого запрещено >>> s[0] = "n" Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment 

Кортежи поддерживают все операции, общие для последовательностей.

3.1.3.1.5. Числовой диапазон¶

Числовой диапазон ( range ) — это упорядоченная неизменяемая последовательность элементов — целых чисел.

  • start (int) – начальное значение (по умолчанию 0);
  • stop (int) – конечное значение (не включается в результат);
  • step (int) – шаг изменения (по умолчанию 1, может быть отрицательным).

В Листинге 3.1.15 приведены примеры генерации числовых последовательностей и их отображение на экране в виде кортежа.

Листинг 3.1.15 — Создание числового диапазона ¶

# 10 чисел (от 0 до 9), начиная с 0 с шагом 1 >>> tuple(range(10)) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) # 10 чисел (от 1 до 10), начиная с 1 с шагом 1 >>> tuple(range(1, 11)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # Числа от 0 до 19 с шагом 5 >>> tuple(range(0, 20, 5)) (0, 5, 10, 15) # Числа от 0 до 20 с шагом 3 >>> tuple(range(0, 20, 3)) (0, 3, 6, 9, 12, 15, 18) # Числа от 0 до -9 с шагом -1 >>> tuple(range(0, -10, -1)) (0, -1, -2, -3, -4, -5, -6, -7, -8, -9) # Следующие 2 объекта range не содержат чисел (нет чисел от 0 до -1 с шагом 1) >>> tuple(range(0)) () >>> tuple(range(1, 0)) () >>> tuple(range(1, 0, -1)) (1,) 

Числовые диапазоны поддерживают те же операции, что и кортежи.

3.1.3.2. Множества¶

Множество — это неупорядоченная коллекция уникальных элементов.

В Python существует 2 класса для работы с множествами:

  • set (изменяемое множество);
  • frozenset (неизменяемое множество).

Элементы множества должны быть хешируемы.

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

Оба типа обладают различиями, схожими с различиями между списком и кортежем.

class set ( [ iterable ] ) ¶ class frozenset ( [ iterable ] ) ¶

Конструкторы классов set и frozenset соответственно.

Создать множество можно несколькими способами (Листинг 3.1.16).

Листинг 3.1.16 — Создание множества ¶
# 1. Пустое множество создается с помощью функции set() >>> set() set() # 2. Инициализировать множество элементами можно, используя: # — фигурные скобки с перечислением элементов; # — функцию set(), передав в качестве аргумента любой итерируемый объект. # Следует обратить внимание, что т.к. множество — неупорядоченный набор данных, # при выводе порядок его элементов может быть произвольным. >>> «a», «b», «c»> >>> set([1, 2, 3, 4, 5])

3.1.3.2.1. Общие операции¶

Пусть st — множество, на котором вызывается метод.

Добавляем элемент elem в множество st .

Удаляет элемент elem из множества st . Если элемент не находится в множестве, возникает ошибка.

Удаляет элемент elem из множества st , если он присутствует в множестве.

Удаляет произвольный элемент из множества st и возвращает в качестве результата.

Удаляет все элементы из множества.

3.1.3.2.2. Математические операции¶

Множества поддерживают математические операции, характерные для множеств (пересечение, объединение и др.), некоторые из которые приведены ниже.

Пусть st — множество, на котором вызывается метод.

union ( other, . ) ¶ st | other | .

Возвращает новое множество — объединение множеств st и other .

intersection ( other, . ) ¶ st & other & .

Возвращает новое множество — пересечение множеств st и other .

difference ( other, . ) ¶ st — other — .

Возвращает новое множество — разность множеств st и other .

Возвращает True если st не содержит общий элементов с other .

Возвращает True если все элементы st содержатся в other .

issuperset ( other ) ¶ st >= other

Возвращает True если все элементы other содержатся в st .

Аналогично st >= other , но множества не должны полностью совпадать.

update ( other, . ) ¶ st |= other | .

Добавляет элементы из other в st .

В Листинге 3.1.17 приведен пример работы с множеством.

Листинг 3.1.17 — Пример работы с множеством ¶
>>> a = 2, 4, 6, 8, 10> >>> b = set(range(11)) >>> a >>> b >>> >>> b.remove(0) >>> b >>> a.add(12) >>> a >>> a & b >>> a | b >>> a b >>> b a

3.1.3.3. Отображения¶

Отображение — это неупорядоченная коллекция пар элементов «ключ-значение». В разных языках синонимом отображений являются термины словарь, хеш-таблица или ассоциативный массив.

Отображения в Python представлены единственным типом dict (словарь), в котором в качестве ключа может выступать любой хешируемый объект, а в качестве значения — произвольный объект.

class dict ( ** kwarg ) ¶ class dict ( mapping , ** kwarg ) class dict ( iterable , ** kwarg )

Создать словарь можно несколькими способами (Листинг 3.1.18).

Листинг 3.1.18 — Создание словаря ¶
# 1. Пустой словарь создается с помощью <> или функции dict() >>> <> <> >>> dict() <> # 2. Инициализировать словарь элементами, используя: # — фигурные скобки с перечислением элементов в виде ‘ключ: значение’; # — функцию dict(), передав набор пар ‘ключ: значение’. # Следует обратить внимание, что т.к. множество — неупорядоченный набор данных, # при выводе порядок его элементов может быть произвольным. >>> «one»: 1, «two»: 2, «three»: 3> >>> dict(one=1, two=2, three=3)

Ниже рассмотрены операции, доступные для словарей.

Пусть d — словарь, на котором вызывается метод.

Возвращает значение словаря для ключа key . Если ключ не существует, возникает ошибка.

Возвращает значение словаря для ключа key . Если ключ не существует возвращается значение default или None .

Устанавливает значение словаря по ключу key . Если ключ не существует, он создается.

Возвращает набор пар «ключ-значение» для словаря d .

Возвращает набор ключей для словаря d .

Возвращает набор значений для словаря d .

Удаляет из словаря все элементы.

Удаляет пару «ключ-значение» на основании ключа key .

В Листинге 3.1.19 приведен пример работы со словарем.

Листинг 3.1.19 — Пример работы со словарем ¶

>>> phonebook = "Петров Петр": "+79102222222"> >>> phonebook["Иванов Сергей"] = "+79101111111" >>> phonebook >>> phonebook["Петров Петр"] '+79102222222' # Обновили номер телефона >>> phonebook["Петров Петр"] = "+79103333333" >>> phonebook >>> "Васильев Василий" in phonebook False >>> phonebook.get("Васильев Василий", "Номер не найден") 'Номер не найден' >>> phonebook.keys() dict_keys(['Иванов Сергей', 'Петров Петр']) >>> phonebook.values() dict_values(['+79101111111', '+79103333333']) 

3.1.4. Еще про объекты и операции¶

3.1.4.1. Общие функции¶

Все объекты независимо от типа поддерживают ряд общих функций.

Возвращает уникальный идентификатор object (для реализации CPython — адрес в памяти).

Возвращает True , если x и y указывают на один и тот же объект.

Отображает справку для object .

Возвращает тип object .

isinstance ( object, class-or-type-or-tuple ) ¶

Возвращает True , если object является классом или подклассом class-or-type-or-tuple .

3.1.4.2. Проверка типов¶

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

Листинг 3.1.20 — Функции type() и isinstance() ¶

>>> a = 5 >>> type(a) is int True >>> isinstance(a, int) True # isinstance может принимать вторым параметром кортеж проверяемых типов >>> isinstance(a, (int, float)) True 

3.1.4.3. Взаимное преобразование¶

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

Листинг 3.1.21 — Взаимное преобразование типов ¶

# 1. Преобразование в строку # Строковое представление имеют практически все рассмотренные классы >>> str(True) 'True' >>> str(5) '5' >>> str(10.43) '10.43' >>> str([1, 2, 3, 4, 5]) '[1, 2, 3, 4, 5]' # 2. Преобразование в целое число >>> int(10.43) # int отсекает дробную часть 10 >>> int("5") 5 >>> int(True) 1 # 3. Преобразование в вещественное число >>> float(5) 5.0 >>> float("10.43") 10.43 # 4. Преобразование в логический тип # Всегда возвращает False, для: # - None, False; # - нулевых чисел; # - пустых последовательностей и отображений. # - . >>> bool(None), bool(0), bool(0.0), bool(""), bool(<>) (False, False, False, False, False) >>> bool(5), bool(1: "первый">) (True, True) # 5. Преобразования последовательностей >>> tuple([1, 2, 3]) (1, 2, 3) >>> d = dict(one=1, two=2, three=2) >>> list(d.keys()) # Получаем список ключей ['one', 'three', 'two'] >>> set(d.values()) # И множество значений >>> 

3.1.4.4. Приоритет операций¶

Операции над объектами выполняются в определенном порядке:

  1. ** .
  2. -x , +x .
  3. * , / , // , % .
  4. + , — .
  5. < , , >= , != , == .
  6. is , is not .
  7. in , not in .
  8. not , and , or .

Изменение порядка можно производить за счет использования скобок, например: (5 + 2) * 3 или (3 * 2)**3 .

3.1.4.5. Поверхностное и глубокое копирование¶

Оператор присваивания копирует ссылку на объект, создавая т.н. поверхностную копию. В ряде случае необходимо создать полную копию объекта (глубокую копию), например, для мутирующих коллекций, чтобы после изменять новую коллекцию без изменения оригинала. Пример различных вариантов копирования приведен в Листинге 3.1.22.

Листинг 3.1.22 — Поверхностное и глубокое копирование объектов ¶

# 1. Поверхностная и глубокая копии >>> x = [53, 68, ["А", "В", "С"]] >>> x1 = x # Поверхностная копия (через присваивание) >>> x2 = x[:] # Глубокая копия (создается при срезе) >>> x3 = x.copy() # Глубокая копия (через метод copy()) >>> >>> id(x), id(x1), id(x2), id(x3) (4813768, 4813768, 4813848, 4813808) >>> x1 is x, x2 is x, x3 is x (True, False, False) # 2. Присваивание копирует ссылки на объекты, создавая объекты при необходимости # Проверить можно с помощью функции id() >>> a = 5 >>> b = a >>> a, b (5, 5) >>> id(a), id(b) (1431495600, 1431495600) >>> c = 5 >>> id(a), id(c) (1431495600, 1431495600) # При изменении значения 'a', Python не изменяет объект 5 # (оставляя его "как есть", т.к. знает, что он используется другими), # а создает новый, меняя ссылку у 'a', при этом прочие объекты продолжают ссылаться на 5 >>> a = 10 >>> id(a), id(c) (1431495680, 1431495600) # Но с мутирующими типами (например, списком) Python поступает по-другому >>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> c = a >>> id(a), id(b), id(c) (30431712, 30447736, 30431712) # При изменении мутирующего типа "изменяются" и указывающие на него объекты - # т.к. они хранят ссылку на тот же объект! >>> a[0] = 5 >>> a, b, c ([5, 2, 3], [1, 2, 3], [5, 2, 3]) 

3.1.4.6. Константы¶

В Python не существует привычного для, например, Си или Паскаля понятия константы. Вместо этого, значение, которое подразумевается как константа, обозначается заглавными буквами ( MEMORY_MAX = 1024 ), визуально предупреждая, что данное значение менять не следует.

3.1.4.7. Сортировка¶

Функция sorted() позволяет получить отсортированный объект в виде списка. В Листинге 3.1.23 приведен пример выполнения сортировки для различных типов коллекций.

Листинг 3.1.23 — Пример использования функции sorted() ¶

# 1. Простой список >>> lst = [1, 8, 2, 5, 0, 3] >>> sorted(lst) [0, 1, 2, 3, 5, 8] >>> sorted(lst, reverse=True) [8, 5, 3, 2, 1, 0] # 2. Словарь # Для словаря sorted() возвращает отсортированный список ключей >>> phones = 'Иван': '+74951111111', 'Сергей': '+74951111113', 'Кирилл': '+74951111112'> >>> sorted(phones) ['Иван', 'Кирилл', 'Сергей'] # 3. Сложная сортировка # Список кортежей: номер элемента, обозначение, название >>> elements = [(1, "Н", "Водород"), (8, "O", "Кислород"), (53, "I", "Йод")] # Используя параметр key, sorted() позволяет сортировать список по # необходимой части коллекции # Сортировка по наименованию (элемент с индексом 2 в кортеже) >>> sorted(elements, key=lambda item: item[2]) [(1, 'Н', 'Водород'), (53, 'I', 'Йод'), (8, 'O', 'Кислород')] # Список чисел >>> nums = [123, 100, 1001, 234, 515] # Сортировка по последней цифре числа по убыванию >>> sorted(nums, key=lambda item: item % 10, reverse=True) [515, 234, 123, 1001, 100] 

3.1.5. Ввод / вывод¶

Обработка данных, как правило, осуществляется после получения данных из какого-либо источника, а после обработки осуществляется их вывод. Для ввода и вывода (в/из терминала операционной системы) в Python используются функции input() и print() соответственно.

Для взаимодействия с терминалом в Python существует 2 функции:

Печатает строку prompt (без переноса строки и если задана) и ожидает ввода пользователя. Ввод подтверждается клавишей , возвращая строку с введенными данными в качестве результата.

print ( * objects , sep = ‘ ‘ , end = ‘\\n’ , file = sys.stdout , flush = False ) ¶

Печатает набор объектов objects , разделенных запятой. При печати все объекты преобразуются в строки.

  • sep – разделитель при выводе нескольких объектов (по умолчанию — пробел);
  • end – строка, завершающая вывод (по умолчанию — перенос строки);
  • file – объект вывода (по умолчанию — терминал).

В Листинге 3.1.24 приведен пример использования функций ввода/вывода.

Листинг 3.1.24 — Пример использования функций ввода/вывода ¶

# 1. Выдать приветствие пользователю >>> name = input("Как тебя зовут? ") Как тебя зовут? Михаил >>> print("Привет,", name, "!") Привет, Михаил ! # 2. Получить длину стороны квадрата (целое число) и вычислить площадь >>> a = int(input("Введите сторону квадрата: ")) Введите сторону квадрата: 15 >>> square = a ** 2 >>> print("Площадь квадрата = <>".format(square)) Площадь квадрата = 225 

Побочный эффект. URL: https://ru.wikipedia.org/wiki/Побочный_эффект_(программирование).

0.30000000000000004 — Floating Point Math. URL: http://0.30000000000000004.com/.

Лучано Рамальо. Python. К вершинам мастерства. — М.: ДМК Пресс , 2016. — 768 с.: ISBN: 978-5-97060-384-0, 978-1-491-94600-8.

Версия: 2023. Обновлено: 16.05.2023.

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

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