Python основы

Февраль 8th, 2019 Рубрики: coding, python
python введение, основы питон

Так складывается судьба, что текущий год я планирую посвятить изучению python. Итак, это будет первая статья о питоне: об установке, базовой настройке и синтаксисе. Простите, если поначалу я что-то буду писать с точки зрения полного нуба и статья будет конских размеров ) В статье будет много листингов и мало картинок. Данная статья о python будет ближайшее время редактироваться и дополняться.

Введение

Родоначальником и великодушным пожизненным диктатором (Benevolent Dictator For Life) до определенного времени был нидерландец Гвидо ван Россум \ Guido van Rossum.

Python - это высокоуровневый, скриптовый интерпретируемый язык программирования общего назначения.
Иными словами,
1. язык сильно изолирован от особенностей железа (в отличие от ассемблеров, С и др.),
2. для работы питона нужен интерпретатор и ...
3. ...python используется для чего угодно )

Стоит так же отметить, что исторически, существует 2 major-версии языка 2.7 и 3.x. При этом, версия 2.7 объявлена End of Life в 2020 году. Поэтому, все что я буду писать - будет относиться только к ветке 3.х (на момент написания статьи - 3.6\3.7) и может не работать на 2.7.

На данный момент мои планы по применению python таковы - основное применение python будет - автоматизация рутинных операций с сетевым и серверным оборудованием, возможно, немного веб и аналитики.

Установка и использование

Установка python этого добра производится тем способом, который ближе по душе. Можно из готовых бинарных пакетов с помощью Вашего любимого пакетного менеджера (apt\yum\zypper), можно из исходников, скачав с сайта разработчика. Как ставить ПО в Linux я уже писал.

Предположим, что у вас стоит Debian, предположим версии buster, в таком случае, установка будет выглядеть так:

apt-get install python3-minimal ipython3

или

apt-get install python3 ipython3

установка пакета ipython3 (Interactive Python) - опциональна. Так получилось, что именно этот интерпретатор на данный момент мне понравился, но стандартный так же функционален, но менее удобен.

Стоит так же отметить, что в python встроен свой менеджер пакетов - PyPi. Т.н. pip или pip3 в зависимости от версии python. Обычно, pip устанавливается сразу с python из бинарников. pip умеет устанавливать пакеты из Python Package Index (PyPi), Github, Bitbucket, Google Code. В PyPi содержатся опенсорс пакеты для Python. В некоторых случаях, использование pip необязательно, т.к. многие популярные модули поставляются в репозиториях Вашего дистрибутива Linux по-умолчанию. Например, Debian buster содержит примерно 1200 пакетов python3, из которые есть что выбрать:

root@deb-buster:~# apt-cache search python3 module | wc -l
1265
root@deb-buster:~#

Запуск интерпретатора python выполняется просто. Ipython:

root@deb-buster:~# ipython3
Python 3.7.2 (default, Jan 3 2019, 02:55:40)
Type "copyright", "credits" or "license" for more information.

IPython 5.8.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]:

или классический python

root@deb-buster:~# python3
Python 3.7.2 (default, Jan 3 2019, 02:55:40)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Выход из питона - либо exit, либо Ctrl + D.

Управление pip

С pip как и с apt\yum\zypper все просто. Запуск pip производится так:

pip sub_command options

или (если по какой-то причине pip не прописан в переменную PATH) так:

python -m pip sub_command options

Управление пакетами:

$ # установить пакет
$ pip install имя_пакета
$ # Обновить пакет:
$ pip install имя_пакета -U
$ # принудительно переустановить пакет (например, определенной версии):
$ pip install --force-reinstall
$ # Посмотреть список установленных пакетов Python
$ pip list
$ # Найти конкретный пакет по имени
$ pip search
$ # справка
$ pip help
$ # удалить пакет
$ pip uninstall имя_пакета

Синтаксис python

Примечание:

Никак не могу себе найти и подобрать хайлайтер кода, чтобы не было проблем с заменой спецсимволов в WordPress. Так что простите за кривое форматирование (((

Эталон синтаксиса языка питон определен в документе PEP 8 — the Style Guide for Python Code.

Основная особенность синтаксиса python - отступы в коде имеют значение. То есть, именно отступы определяют, где начинается логический блок, а где заканчивается.

a = 10
b = 5

if a > b:
print("A больше B")
print(a - b)
else:
print("B больше или равно A")
print(b - a)

print("The End")

def open_file(filename):
print("Reading file", filename)
with open(filename) as f:
return f.read()
print("Done")

Давайте рассмотрим блок кода выше. Первые 2 строки - это назначение имени переменной (о них ниже). Далее, идет блок кода оператора условия - if. Прои if будет в другой статье. Далее, производится печать строки The end с помощью функции print. И последний блок - это определение функции open_file. Про функции так же будет отдельная статья.

Словами синтаксис можно описать так: (выражение, двоеточие(после двоеточия всегда идет строка с отступом)), (с новой строки отступ, новое выражение(которое является дочерним для исходного выражения)), (на новой строке так же отступ (который ровно такой же, как в предыдущей строке), новое выражение) ... Вложенность выражении не ограничена.

Для понимания процесса, самое время рассказать о том, что существуют логические и физические строки. Физическая строка – это то, что вы вводите и видите в интерпретаторе или скрипте, когда набираете программу. Логическая строка – это то, что интерпретатор Python видит как единое предложение. В общем случае, логическая строка соответствует физической. Но..., как всегда, есть нюансы. В примере выше, строка print("The End") соответствует физической и логической. Стандарт PEP своими правилами стимулирует, чтобы код всегда соответствовал правилу одна физическая строка == одна логическая строка.

Можно на одной физической строке записать несколько логических. Для отделения одной логической строки от физической python использует символ ; . Но так делать не рекомендуется! Пример двух логических строк на одной физической:

# две логические и две физические строки
a = 5
print(a)
# тот же код, но в одной физической строке:
a = 5; print(a)

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

  • В качестве отступов могут использоваться Tab или пробелы.
    • лучше использовать пробелы, а точнее, настроить редактор так, чтобы Tab был равен 4 пробелам
  • Размеры отступов количество пробелов должно быть одинаковым во всем коде

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

Начнем с снов

 In [1]: # комментарий
In [2]: var=5
In [3]: var=5000
In [4]: var =5000
In [5]: var = 5000
In [7]: """ Как можно видеть,
…: это многострочный комментарий,
…: но PEP8 рекомендует использовать #
…: """
Out[7]: ' Как можно видеть, \nэто многострочный комментарий\n'
In [8]: var2 = 6000 # и это после символа # - комментарий
In [9]: # Как можно видеть, python лоялен к пробелам

Математические операции и операции сравнения python

# интерпретатор умеет базовые математические 
# сложение
In [14]: 2 + 1
Out[14]: 3
# вычитание
In [15]: 100 - 45
Out[15]: 55
# умножение
In [16]: 20 * 45
Out[16]: 900
# деление
In [18]: 45 / 21
Out[18]: 2.142857142857143
# деление с усечением (отсечение остатка)
In [19]: 45 // 21
Out[19]: 2
# деление по модулю (остаток от деления)
In [20]: 45 % 21
Out[20]: 3
# возведение в степень
In [21]: 2 ** 3
Out[21]: 8
# приоритет выполнения нескольких операторов /
# соответствует школьному курсу)
In [175]: 2 + 2 * 2
Out[175]: 6
# упрощенное представление операций (применимо ко всем операциям):
In [20]: a = 2
In [21]: a = a * 3
# то же, но сокращенно:
In [20]: a = 2
In [21]: a *= 3
# стандартный набор операций сравнения
In [88]: 10 > 3.0
Out[88]: True

In [89]: 10 < 3
Out[89]: False

In [90]: 10 == 3
Out[90]: False

In [91]: 10 >= 10
Out[91]: True

In [93]: 10<=10
Out[93]: True

In [94]: 10.0 == 10
Out[94]: True

In [95]: 10 !=11
Out[95]: True

Получение помощи по объекту, функции или методу выполняется так(в ipython): help(str) или str? или ?str.

Разное

# print выводит (по умолчанию) на stdout содержимое (строку, число,  /
# значение вычисления) и добавляет в конце вывода перенос строки
In [27]: ?print
Docstring:
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
Type: builtin_function_or_method

In [28]: print('строка')
строка

In [30]: print(2)
2

In [31]: print(2+3)
5
# dir() - отображение методов и атрибутов объекта
In [32]: dir(str)
Out[32]:
['__add__',
'__class__',
<...>
'swapcase',
'title',
'translate',
'upper',
'zfill']

In [33]: dir(help)
Out[33]:
['__call__',
'__class__',
<...>
'__subclasshook__',
'__weakref__']

In [34]: a = 2

In [35]: dir(a)
Out[35]:
['__abs__',
'__add__',
<...>
'numerator',
'real',
'to_bytes']
# удаление объекта (все что угодно - переменная, импортированный модуль, строка и т.д.)
In [36]: del object
# функция id() возвращает идентификатор object's memory address для любого объекта
# особенно полезна при траблшутинге (примеры - ниже)
In [59]: id(str)
Out[59]: 8522816
# функция type() выводит тип объекта
In [124]: type([])
Out[124]: list

In [125]: type(())
Out[125]: tuple

In [126]: type('')
Out[126]: str

In [127]: type(1)
Out[127]: int

In [128]: type({})
Out[128]: dict

In [130]: type(str)
Out[130]: type

In [131]: type(str.upper)
Out[131]: method_descriptor

Переменные

python - язык с динамической типизацией, поэтому указывать тип переменной при создании переменной - нет необходимости - тип определяется динамически.
Переменная в питоне - это ярлык, который указывает на область памяти. Если область памяти (контейнер) не изменяемая, при повторном определении переменной - создается новый контейнер и уже на новый контейнер ссылается "ярлык". Старый контейнер очищается служебным процессом garbige collector.

In [69]: a = 3

In [70]: b = 'nice'

In [71]: c, d = 9, 'hello'
# 3 переменные ссылаются на один контейнер
In [72]: e = f = g = 6778899

In [73]: print(a, b, c, d, e, f, g)
3 nice 9 hello 6778899 6778899 6778899

In [74]: id(e)
Out[74]: 140000835718192

In [75]: id(f)
Out[75]: 140000835718192

In [76]: id(g)
Out[76]: 140000835718192
# если переменную переопределить, то создается новый контейнер
In [77]: f = 6778899

In [78]: id(f)
Out[78]: 140000834855440

In [79]: id(e)
Out[79]: 140000835718192

In [80]: f = 10000

In [81]: id(f)
...:
Out[81]: 140000834855216

In [82]: id(e)
Out[82]: 140000835718192

Именование функций, классов и переменных выполняется так же по идеологии PEP8:

  • имена переменных пишутся полностью большими или маленькими буквами
    • DB_NAME
    • db_name
  • имена функций задаются маленькими буквами, с подчеркиваниями между словами
    • get_names
  • имена классов задаются словами с заглавными буквами, без пробелов
    • CiscoSwitch

TODO: область видимости переменной!

Функции и методы

Функции – это многократно используемые фрагменты кода программы. Функция имеет имя в любом месте программы можно использовать созданный блок кода по его имени - т.н. вызывать функцию. Функция может быть написана локально в скрипте, а может быть встроенной в интерпретатор, либо в модуль.
Если функция привязана к определенному объекту и\или типу объекта, она называется методом.

Ниже, при рассмотрении типов данных будут примеры встроенных функций - id(), int(), round() и др. Доступ к методу какого-то объекта выполняется конструкцией объект.метод().

Типы данных PYTHON

Переменные могут хранить значения разных типов, называемых типами данных.

В данном случае, упорядоченные (индексированные) - значит объект (список, строка, кортеж) состоит из подобъектов\элементов (символы, значения), к которым можно обратиться и получить этот подобъект - последовательно по адресу, а так же, выполнить операцию проверки принадлежности (т.е. выражения "in" и "not in"), неупорядоченные - значит содержимое объекта не упорядочено и значение объекта можно вывести только по его имени. Неизменяемые - значит данные нельзя изменить напрямую. Например, при присваивании переменной - будет создан новый объект в памяти, а старый будет удален.

Числа Numbers

Числа в питоне бывают 3 типов: int (целое число), float (с плавающей точкой) и комплексные (???). В коде - числа отличаются от строк - отсутствием кавычек (число: 1, строка: '1').

In [97]: 10 / 3
Out[97]: 3.3333333333333335

In [98]: 10 / 3.0
Out[98]: 3.3333333333333335
# округление до 3 символа после зпт
In [99]: round(10/3, 3)
Out[99]: 3.333
# округление до 1 символа после зпт
In [100]: round(10/3, 1)
Out[100]: 3.3
# преобразование строки в число типа int
In [103]: a = '1000'

In [104]: int(a)
Out[104]: 1000
# отображение переменной а в десятичном виде,
# как будто она записана в двоичном
In [111]: int(a, base=2)
Out[111]: 8
# bin - возвращает двоичное число
In [114]: bin (8)
Out[114]: '0b1000'

In [115]: bin(int(a, base=2))
Out[115]: '0b1000'
# hex возвращает шестнадцатеричное число
In [117]: hex(10)
Out[117]: '0xa'
# для более сложных операций есть модуль math
In [118]: import math

In [119]: math.pi
Out[119]: 3.141592653589793

Cтроки 'Strings' - str()

Строка в Python:

  • 'последовательность символов, заключенная в кавычки'
  • "неизменяемый упорядоченный тип данных"

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

In [121]: "hello"
Out[121]: 'hello'

In [122]: 'hello'
Out[122]: 'hello'

In [123]: string = '''многострочная строка
...: еще продолжение
...: и еще
...: эээ
...: '''

In [124]: string
Out[124]: 'многострочная строка\nеще продолжение\nи еще\nэээ\n'

In [125]: print(string)
многострочная строка
еще продолжение
и еще
эээ

# объединение
In [126]: "hello"'John'
Out[126]: 'helloJohn'

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

In [128]: hello = 'hello'

In [129]: john = 'john'
# суммирование
In [130]: hello + john
Out[130]: 'hellojohn'

In [131]: hello + ' '+ john
Out[131]: 'hello john'
# умножение
In [132]: hello * 5
Out[132]: 'hellohellohellohellohello'
# отображение к ПЕРВОМУ символу строки
In [135]: hello[0]
Out[135]: 'h'

In [136]: hello[1]
Out[136]: 'e'

In [137]: hello[2]
Out[137]: 'l'
# отображение ПОСЛЕДНЕГО символа строки
In [138]: hello[-1]
Out[138]: 'o'
# срез - с первого по четвертый символ (не включая четвертый)
In [139]: hello[0:3]
Out[139]: 'hel'
# срез - со второго по пятый символ (не включая пятый)
In [140]: hello[1:4]
Out[140]: 'ell'
# срез - со второго по конец строки
In [141]: hello[1:]
Out[141]: 'ello'
# срез - с третьего с конца по конец строки
In [142]: hello[-3:]
Out[142]: 'llo'
# в обратном порядке
In [144]: hello[::-1]
Out[144]: 'olleh'
# в обратном порядке и отобразить с конца три символа
In [145]: hello[-3::-1]
Out[145]: 'leh'
# последние три символа и до конца строки
In [146]: hello[-3::]
Out[146]: 'llo'
In [153]: variable = '123456789'
# отобразить каждый второй символ
In [154]: variable[::2]
Out[154]: '13579'
# отобразить каждый третий символ
In [155]: variable[::3]
Out[155]: '147'
# все упорядоченные объекты можно задействовать в цикле
In [121]: hello = 'hello'
In [122]: for i in hello:
…: print(i)
…:
h
e
l
l
o

Методы строк

МетодОписание
capitalize() Преобразует первый символ в верхний регистр.
count(sub [,start [,end]]) Подсчитывает число вхождений заданной подстроки sub.
endswith(suffix [,start [,end]]) Проверяет, оканчивается ли строка подстрокой suffix.
find(sub [, start [,end]]) Отыскивает первое вхождение подстроки sub или возвращает -1.
index(sub [, start [,end]]) Отыскивает первое вхождение подстроки sub или возбуждает исключение.
isalnum() Проверяет, являются ли все символы в строке алфавитно-цифровыми символами.
isalpha() Проверяет, являются ли все символы в строке алфавитными символами.
isdigit() Проверяет, являются ли все символы в строке цифровыми символами.
islower() Проверяет, являются ли все символы в строке символами нижнего регистра.
isspace() Проверяет, являются ли все символы в строке пробельными символами.
istitle() Проверяет, являются ли первые символы всех слов символами верхнего регистра.
isupper() Проверяет, являются ли все символы в строке символами верхнего регистра.
join()Объединяет несколько строк в одну, вставляя между строками указанный разделитель. (будет рассмотрен в разделе Списки)
lower() Преобразует символы строки в нижний регистр.
lstrip([chrs]) Удаляет начальные пробельные символы или символы, перечисленные в аргументе chrs.
replace(old, new [,maxreplace]) Замещает подстроку old подстрокой new.
rfind(sub [,start [,end]]) Отыскивает последнее вхождение подстроки.
rindex(sub [,start [,end]]) Отыскивает последнее вхождение подстроки или возбуждает исключение.
rstrip([chrs]) Удаляет конечные пробельные символы или символы, перечисленные в аргументе chrs.
startswith(prefix [,start [,end]]) Проверяет, начинается ли строка подстрокой prefix.
strip([chrs]) Удаляет начальные и конечные пробельные символы или символы, перечисленные в аргументе chrs.
swapcase() Приводит символы верхнего регистра к нижнему, и наоборот.
title() Возвращает версию строки, в которой первые символы всех слов приведены к верхнему регистру.
upper()
Преобразует символы строки в верхний регистр.
# примеры методов, принадлежащим к типу данных str
In [158]: string1 = 'FastEthernet'
# преобразовать в верхний регистр
In [159]: string1.upper()
Out[159]: 'FASTETHERNET'
# преобразовать в нижний регистр
In [160]: string1.lower()
Out[160]: 'fastethernet'
# инвертировать регистр
In [161]: string1.swapcase()
Out[161]: 'fASTeTHERNET'
# стоит помнить, что строка - неизменяема и в данном случае \
#будет создан новый контейнер и новому контейнеру присвоится ярлык
In [162]: string1 = string1.upper()

In [163]: string1
Out[163]: 'FASTETHERNET'

In [166]: string1 = 'interface FastEthernet0/1'
# метод подсчета вхождений искомых значений
In [167]: string1.count('fa')
Out[167]: 1

In [168]: string1.count('er')
Out[168]: 2
# метод поиска вхождений искомых значений /
#и возврат номера первого символа
In [169]: string1.find('Fast')
Out[169]: 10
# комбинация find и среза
In [170]: string1[string1.find('Fast')::]
Out[170]: 'FastEthernet0/1'
# метод проверки начинается ли строка с заданного значения
In [171]: string1.startswith('Fa')
Out[171]: False

In [172]: string1.startswith('inter')
Out[172]: True
# метод проверки оканчивается ли строка на заданное значение
In [173]: string1.endswith('0/1')
Out[173]: True
# замена символов
In [174]: string1.replace('Fast', 'Gigabit')
Out[174]: 'interface GigabitEthernet0/1'

In [176]: string1 = '\n\tinterface FastEthernet0/1\n'

In [177]: print(string1)

interface FastEthernet0/1

# очистка строки от whitespace символов (\t\n\r\f\v)
# если аргументом указать символ явно, то очистка будет от заданного символа
# есть так же методы rstrip() и lstrip(), удаляющие справа и слева соответственно
In [178]: string1.strip()
Out[178]: 'interface FastEthernet0/1'
# разбить строку на список, разделить - заданные символы
In [190]: string1.split('er')
Out[190]: ['\n\tint', 'face FastEth', 'net0/1\n']

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

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]

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

Например, таким образом можно вывести данные столбцами одинаковой ширины по 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("{:15} {:15} {:15}".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("{:.3f}".format(10.0/3))
3.333
#конвертировать числа в двоичный формат
In [11]: '{:b} {:b} {:b} {:b}'.format(192, 100, 1, 1)
Out[11]: '11000000 1100100 1 1'
# указывать дополнительные параметры, например, ширину столбца:
In [12]: '{:8b} {:8b} {:8b} {:8b}'.format(192, 100, 1, 1)
Out[12]: '11000000 1100100 1 1'
# дополнить числа нулями, вместо пробелов:
In [13]: '{:08b} {:08b} {:08b} {:08b}'.format(192, 100, 1, 1)
Out[13]: '11000000 01100100 00000001 00000001'
# с именами
In [15]: '{ip}/{mask}'.format(mask=24, ip='10.1.1.1')
Out[15]: '10.1.1.1/24'
# указание номера аргумента:
In [16]: '{1}/{0}'.format(24, '10.1.1.1')
Out[16]: '10.1.1.1/24'
# можно избавиться от дублирования:
In [19]: ip_template = '''
...: IP address:
...: {:<8} {:<8} {:<8} {:<8}
...: {:08b} {:08b} {:08b} {:08b}
...: '''

In [20]: print(ip_template.format(192, 100, 1, 1, 192, 100, 1, 1))

IP address:
192 100 1 1
11000000 01100100 00000001 00000001

In [21]: ip_template = '''
...: IP address:
...: {0:<8} {1:<8} {2:<8} {3:<8}
...: {0:08b} {1:08b} {2:08b} {3:08b}
...: '''

In [22]: print(ip_template.format(192, 100, 1, 1))

IP address:
192 100 1 1
11000000 01100100 00000001 00000001

Cписки [Lists] - list()

Список в python:

  • изменяемый упорядоченный тип данных.
  • [последовательность, элементов,,, разделенных, между, собой, запятой, и, заключенных, в, квадратные, скобки]
# обычный список из чисел
In [22]: list = [10,20,30,40]
# список из строк и чисел
In [23]: list1 = ['abc',20,3.0,40]
# список из списка [1,2,3] и чисел и строк
In [24]: list2 = [[1,2,3],'abc',123]
# создание списка из строки
In [80]: list_from_string = list('string')
In [81]: list_from_string
Out[81]: ['s', 't', 'r', 'i', 'n', 'g']
# обращение к элементу списка
In [26]: list1[1]
Out[26]: 20

In [27]: list1[0]
Out[27]: 'abc'
# обращение к элементу, который является вложенным списком
In [29]: list2[0]
Out[29]: [1, 2, 3]
# обращение к элементу списка списка (сложенного)
In [30]: list2[0][0]
Out[30]: 1
# срез (по аналогии со строками
In [33]: list2[1:3]
Out[33]: ['abc', 123]
# изменение элемента списка
In [34]: list[1] = 100

In [35]: list
Out[35]: [10, 100, 30, 40]
# списки так же можно создавать с помощью генераторов списков,
# например, посмотрите на этот синтаксис (..кровь из глаз)
In [110]: listone = [2, 3, 4]
# необходимо сгенерировать новый список listtwo из значений,
# которые больше 2 и помножены на 3
In [111]: listtwo = [3*i for i in listone if i > 2]

In [112]: listtwo
Out[112]: [9, 12]
# все упорядоченные объекты можно использовать в цикле, например
In [120]: for i in listone:
…: print(i)
…:
2
3
4

Методы списков

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

МетодОписание
list(s)Преобразует объект s в список.
l.append(x)Добавляет новый элемент x в конец списка l.
l.extend(t)Добавляет новый список t в конец списка l.
l.count(x)Определяет количество вхождений x в список l.
l.index(x [,start [,stop]])Возвращает наименьшее значение индекса i, где s[i] == x. Необязательные значения start и stop определяют индексы начального и конечного элементов диапазона, где выполняется поиск.
l.insert(i,x)Вставляет x в элемент с индексом i.
l.pop([i])Возвращает i-й элемент и удаляет его из списка. Если индекс i не указан, возвращается последний элемент.
l.remove(x)Отыскивает в списке s элемент со значением x и удаляет его.
l.reverse()Изменяет порядок следования элементов в списке l на обратный.
l.sort([key [,reverse]])Сортирует элементы списка l. key – это функция, которая вычисляет значение ключа. reverse – признак сортировки в обратном порядке. Аргументы key и reverse всегда должны передаваться как именованные аргументы.
# примеры использования методов
In [56]: list = ['1','2','3','abcd']
# отдельного join для метода списка - нет, но можно использовать join
# для строки('+'), которая будет использована как соединитель для переданного списка
In [57]: '+'.join(list)
Out[57]: '1+2+3+abcd'
# добавление в конец списка
In [58]: list.append('qwer')

In [59]: list
Out[59]: ['1', '2', '3', 'abcd', 'qwer']

In [60]: list2 = [0,9,8,7]
# объединение списков
In [61]: list.extend(list2)

In [62]: list
Out[62]: ['1', '2', '3', 'abcd', 'qwer', 0, 9, 8, 7]

In [63]: list2
Out[63]: [0, 9, 8, 7]
# суммирование (исходный при этом - не меняется)
In [65]: list + list2
Out[65]: ['1', '2', '3', 'abcd', 'qwer', 0, 9, 8, 7, 0, 9, 8, 7]

In [66]: list
Out[66]: ['1', '2', '3', 'abcd', 'qwer', 0, 9, 8, 7]

In [67]: list2
Out[67]: [0, 9, 8, 7]
# удаление заданного объекта по его номеру в списке (также возвращает значение)
In [68]: list.pop(-1)
Out[68]: 7

In [69]: list2
Out[69]: [0, 9, 8, 7]

In [70]: list
Out[70]: ['1', '2', '3', 'abcd', 'qwer', 0, 9, 8]
# удаление объекта по его значению
In [71]: list.remove(0)

In [72]: list
Out[72]: ['1', '2', '3', 'abcd', 'qwer', 9, 8]
# вывод порядкового номера объекта по его значению
In [74]: list.index('abcd')
Out[74]: 3
# вставка объекта на указанное место
In [75]: list.insert(1,'asdf')

In [76]: list
Out[76]: ['1', 'asdf', '2', '3', 'abcd', 'qwer', 9, 8]

Словари {Dictionaries} - dict()

{С:л,о:в,а:р,ь:}

  • изменяемый неупорядоченный тип данных
  • данные в словаре - это пары ключ: значение
  • Несмотря на то, что этот тип объекта неупорядочен, для доступа к значениям можно использовать - ключ, а не номер, как в списках
  • так как словари изменяемы, то элементы словаря можно менять, добавлять, удалять
  • ключ должен быть объектом неизменяемого типа:
    • число
    • 'строка'
    • (к,о,р,т,е,ж)
  • значение может быть любого типа
#Итак, как словари выглядят?
# создадим словать из 3х объектов:
In [3]: person = {
...: 'name': 'Mike' ,
...: 'city' : 'Vologda' ,
...: 'age' : 10
...: }

In [4]: person
Out[4]: {'name': 'Mike', 'city': 'Vologda', 'age': 10}
# создадим простой словать из 3х объектов, при этом,
# значение каждого объекта - это вложенный словарь,
# а второй объект указан как переменная person, которая определена ранее
In [5]: persons = {
...: 1 : {'name': 'John', 'city': 'Moscow', 'age': 25} ,
...: 2 : person ,
...: 3 : {'name': 'Maks', 'city': None, 'age': 99}
...: }

In [6]: persons
Out[6]:
{1: {'name': 'John', 'city': 'Moscow', 'age': 25},
2: {'name': 'Mike', 'city': 'Vologda', 'age': 10},
3: {'name': 'Maks', 'city': None, 'age': 99}}
# создать словать можно так же, с помощью функции dict()
# стоит обратить внимание, что значение первого элемента - это вложенный dict()
In [36]: newdictionary6 = dict(name=dict(test='123'), city='Moscow', age=25)

In [37]: newdictionary6
Out[37]:
{'name': {'test': '123'},
'city': 'Moscow',
'age': 25}
# или так
In [15]: newdictionary2 = dict([('name','John'),('city','Moscow'),('age',25)])

In [16]: newdictionary2
Out[16]: {'name': 'John', 'city': 'Moscow', 'age': 25}
# Если мы знаем, что у нас есть ключи, можно еще создать словарь с помощью dict.fromkeys()

In [18]: dict_keys = ['name', 'city', 'age']

In [19]: newdictionary3 = dict.fromkeys(dict_keys)
# если функции не переданы значения, они заполняются None, ...
In [20]: newdictionary3
Out[20]: {'name': None, 'city': None, 'age': None}
# ... но дефолтное значение можно передать (в данном случае - 'to_be_defined_later')
In [21]: newdictionary3 = dict.fromkeys(dict_keys,'to_be_defined_later')

In [22]: newdictionary3
Out[22]:
{'name': 'to_be_defined_later',
'city': 'to_be_defined_later',
'age': 'to_be_defined_later'}
# можно еще создавать словари генератором, но я не могу пока понять, как это работает:
In [29]: newdictionary5 = {key: [] for key in dict_keys}

In [30]: newdictionary5
Out[30]: {'name': [], 'city': [], 'age': []}
# Обращение к значению производится по имени ключа
In [37]: person
Out[37]: {'name': 'Mike', 'city': 'Vologda', 'age': 10}

In [38]: person['name']
Out[38]: 'Mike'
# обращение к объекту вложенного словаря производится так же по ключу
In [39]: persons
Out[39]:
{1: {'name': 'John', 'city': 'Moscow', 'age': 25},
2: {'name': 'Mike', 'city': 'Vologda', 'age': 10},
3: {'name': 'Maks', 'city': None, 'age': 99}}

In [40]: persons[3]['name']
Out[40]: 'Maks'
# изменить значение так же по ключу
In [42]: person['name'] = 'NoName'

In [43]: person
Out[43]: {'name': 'NoName', 'city': 'Vologda', 'age': 10}
# удаление пары ключ: значение
In [45]: del person['age']

In [46]: person
Out[46]: {'name': 'NoName', 'city': 'Vologda'}
# добавление новой пары ключ: значение
In [47]: person['newkey'] = 'newvalue'

In [48]: person
Out[48]: {'name': 'NoName', 'city': 'Vologda', 'newkey': 'newvalue'}
# вывести количество элементов в словаре
In [50]: len(person)
Out[50]: 3

In [51]: len(persons)
Out[51]: 3
# оператор in возвращает True если ключ есть в словаре
In [57]: 'name' in person
Out[57]: True

In [58]: 'age' in person
Out[58]: False
# важной особенностью словарей python является то, что они изменяемые,
# то есть создавая в памяти объект словаря и присваивая ему имя переменной,
# (или два имени переменной, или три) и изменяя словарь, эти изменения
# будут видны по всем именам:
In [64]: person
Out[64]: {'name': 'NoName', 'city': 'Vologda', 'newkey': 'newvalue'}
# присвоим новое имя
In [65]: person2 = person

In [66]: person2
Out[66]: {'name': 'NoName', 'city': 'Vologda', 'newkey': 'newvalue'}
# как видно, у обоих объектов - один идентификатор
In [67]: id(person)
Out[67]: 140602802378432

In [69]: id(person2)
Out[69]: 140602802378432
# Изменим значение ключа 'newkey'
In [70]: person2['newkey'] = None
# оба словаря отображают изменения
In [71]: person2
Out[71]: {'name': 'NoName', 'city': 'Vologda', 'newkey': None}

In [72]: person
Out[72]: {'name': 'NoName', 'city': 'Vologda', 'newkey': None}

Методы словарей - dict.methods()

МетодОписание
d.clear()Удаляет все элементы из словаря d.
d.copy()Создает копию словаря d.
d.fromkeys(s [,value])Создает новый словарь с ключами, перечисленными в последовательности s, а все значения устанавливает равными value.
d.get(k [,v])Возвращает элемент d[k], если таковой имеется, в противном случае возвращает v.
d.items()Возвращает последовательность пар (key, value).
d.keys()Возвращает последовательность ключей.
d.pop(k [,default])Возвращает элемент d[k], если таковой имеется, и удаляет его из словаря; в противном случае возвращает default, если этот аргумент указан, или возбуждает исключение KeyError.
d.popitem()Удаляет из словаря случайную пару (key, value) и возвращает ее в виде кортежа.
d.setdefault(k [, v])Возвращает элемент d[k], если таковой имеется, в противном случае возвращает значение v и создает новый элемент словаря d[k] = v.
d.update(b)Добавляет все объекты из b в словарь d.
d.values()Возвращает последовательность всех значений в словаре d.
# ПРИМЕРЫ работы с методами словарей disct
# если мы обратимся к несуществующему ключу, то вывалится ошибка KeyError
In [77]: person[1341234]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
in ()
----> 1 person[1341234]

KeyError: 1341234

# данной ошибки можно избежать, если использовать метод dict.get()
# если ключа нет, он вернет значение None (или заданное)
In [79]: print (person.get(1234))
None
# dict.setdefault() вернет значение запрошенного ключа, но если его нет, то создаст новый со значением None
In [81]: person.setdefault('city')
Out[81]: 'Vologda'

In [82]: person.setdefault('not_exist_key')

In [83]: person
Out[83]: {'name': 'NoName', 'city': 'Vologda', 'newkey': None, 'not_exist_key': None}
# но если указать ключ и значение, то для несуществующего будет создан ключ вместе со значением
In [84]: person.setdefault('not_exist_key', 'nevalue')

In [85]: person
Out[85]: {'name': 'NoName', 'city': 'Vologda', 'newkey': None, 'not_exist_key': None}

In [86]: person.setdefault('not_exist_key_2', 'newvalue')
Out[86]: 'newvalue'

In [87]: person
Out[87]:
{'name': 'NoName',
'city': 'Vologda',
'newkey': None,
'not_exist_key': None,
'not_exist_key_2': 'newvalue'}
# данная функция заменяет вот такую конструкцию
In [90]: if 'key' in person:
...: value = person['key']
...: else:
...: person['key'] = 'stringvalue'
...: value = person['key']
...:
...:

In [91]: person
Out[91]:
{'name': 'NoName',
'city': 'Vologda',
'newkey': None,
'not_exist_key': None,
'not_exist_key_2': 'newvalue',
'key': 'stringvalue'}

In [92]: value
Out[92]: 'stringvalue'
# метод dict.keys(), dict.values(), dict.items() возвращает список ключей, значений и пар ключ: значение
In [93]: person.keys()
Out[93]: dict_keys(['name', 'city', 'newkey', 'not_exist_key', 'not_exist_key_2', 'key'])

In [94]: person.values()
Out[94]: dict_values(['NoName', 'Vologda', None, None, 'newvalue', 'stringvalue'])

In [96]: person.items()
Out[96]: dict_items([('name', 'NoName'), ('city', 'Vologda'), ('newkey', None), ('not_exist_key', None), ('not_exist_key_2', 'newvalue'), ('key', 'stringvalue')])

In [97]: persons.items()
Out[97]: dict_items([(1, {'name': 'John', 'city': 'Moscow', 'age': 25}), (2, {'name': 'NoName', 'city': 'Vologda', 'newkey': None, 'not_exist_key': None, 'not_exist_key_2': 'newvalue', 'key': 'stringvalue'}), (3, {'name': 'Maks', 'city': None, 'age': 99})])
# метод dict.update() добавляет к имеющемуся словарю значения из нового
# если в словаре уже есть аналогичные ключи, то значения обновляются
In [100]: newdictionary
Out[100]: {'name': 'John', 'city': 'Moscow', 'age': 25}

In [101]: person
Out[101]:
{'name': 'NoName',
'city': 'Vologda',
'newkey': None,
'not_exist_key': None,
'not_exist_key_2': 'newvalue',
'key': 'stringvalue'}

In [102]: person.update(newdictionary)

In [103]: person
Out[103]:
{'name': 'John',
'city': 'Moscow',
'newkey': None,
'not_exist_key': None,
'not_exist_key_2': 'newvalue',
'key': 'stringvalue',
'age': 25}

Кортежи (Tuples) - tuple(,,)

(К,о,р,т,е,ж) - почти как [с,п,и,с,о,к], только не_изменяемый. Последовательность в кортеже записывается в круглые скобки, через запятую.

# Примеры работы с кортежами
# создание кортежа:
In [139]: tuple1 = tuple()

In [140]: type(tuple1)
Out[140]: tuple

In [141]: tuple1
Out[141]: ()
# при создании кортежа из одного элемента, необходимо указать запятую ...
In [142]: tuple2 = (1,)

In [143]: tuple3 = (1)
# ... иначе - это будет список
In [144]: type(tuple3)
Out[144]: int

In [145]: type(tuple2)
Out[145]: tuple
# кортеж можно создать из списка
In [147]: listone
Out[147]: [2, 3, 4]

In [148]: tuple4 = tuple(listone)

In [149]: tuple4
Out[149]: (2, 3, 4)
# Кортеж нельзя изменить
In [150]: tuple4[0]
Out[150]: 2

In [151]: tuple4[1] = 10
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
----> 1 tuple4[1] = 10

TypeError: 'tuple' object does not support item assignment

Методы кортежей - tuple.methods()

В общем-то тут все тоже самое, что со списками, с учетом того, что кортеж - не изменяемый.

Множества {Sets} - set()

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

Особенность множества в том, что можно сравнить 2 множества и проверить принадлежность (пересечения) элементов одного в другом и наоборот.

#Примеры работы с множествами
# Создать множество из разных типов значений (int, str, dict, list)...
# ... из int
In [186]: set2 = {10,20,100,30}

In [187]: type(set2)
Out[187]: set
# ... из str
In [190]: set3 = {'10','20','100','30'}
# ... или тоже из str
In [206]: set9 = set('string ')

In [207]: print(set9)
{'t', ' ', 'i', 'g', 'n', 'r', 's'}
# ... из list
In [191]: set3 = {(1,2,3),(2,3,4)}

In [192]: type(set3)
Out[192]: set

In [193]: print(set3)
{(2, 3, 4), (1, 2, 3)}
# ... комбинированный
In [195]: set4 = {(1,2,3),('2','3','4'),"sdf"}

In [197]: print(set4)
{('2', '3', '4'), 'sdf', (1, 2, 3)}
# множество - не упорядочено, поэтому невозможно обратиться по индексу
In [198]: set4[0]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
ipython-input-198-6219112fe719 in module()
----> 1 set4[0]

TypeError: 'set' object does not support indexing
# создать множество из списка
In [165]: listintgrs = [1,2,100,2,1,50]

In [167]: setfromlis = set(listintgrs)
# то же самое можно сделать так:
# setfromlis = set( [1,2,100,2,1,50] )
In [168]: setfromlis
Out[168]: {1, 2, 50, 100}
# можно так же генератором (...опять этот синтаксис)
In [214]: setfromgen = {i + 5 for i in range(10)}

In [215]: print(setfromgen)
{5, 6, 7, 8, 9, 10, 11, 12, 13, 14}

In [216]: type(setfromgen)
Out[216]: set
# проверка
In [169]: 5 in setfromlis
Out[169]: False

In [170]: 50 in setfromlis
Out[170]: True

In [172]: for i in setfromlis:
...: print(i)
...:
1
2
100
50

Методы множеств - set.methods()

МетодОписание
s.copy()Создает копию множества s.
s.difference(t)Разность множеств. Возвращает все элементы из множества s, отсутствующие в t.
s.intersection(t)Пересечение множеств. Возвращает все элементы, присутствующие в обоих множествах s и t.
s.isdisjoint(t)Возвращает True, если множества s и t не имеют общих элементов.
s.issubset(t)Возвращает True, если множество s является подмножеством t.
s.issuperset(t)Возвращает True, если множество s является надмножеством t.
s.symmetric_difference(t)Симметричная разность множеств. Возвращает все элементы, которые присутствуют в множестве s или t, но не в обоих сразу.
s.union(t)Объединение множеств. Возвращает все элементы, присутствующие в множестве s или t.
s.add(item)Добавляет элемент item в s. Ничего не делает, если этот элемент уже имеется в множестве.
s.clear()Удаляет все элементы из множества s.
s.difference_update(t)Удаляет все элементы из множества s, которые присутствуют в t.
s.discard(item)Удаляет элемент item из множества s. Ничего не делает, если этот элемент отсутствует в множестве.
s.intersection_update(t)Находит пересечение s и t и оставляет результат в s.
s.pop()Возвращает произвольный элемент множества и удаляет его из s.
# примеры работы методов множеств
# добавить элемент ко множеству
In [173]: setfromlis.add(13)

In [175]: print(setfromlis)
{1, 2, 100, 13, 50}
# удалить элемент из множества, если он есть ...
In [176]: setfromlis.discard(100)

In [177]: print(setfromlis)
{1, 2, 13, 50}
# ... если элемента нет, ошибка так же не возвращается
In [178]: setfromlis.discard(100)

In [179]: print(setfromlis)
{1, 2, 13, 50}
# удалить все элементы из множества
In [181]: setfromlis.clear()

In [182]: print(setfromlis)
set()

In [183]: setfromlis = set(listintgrs)

In [184]: print(setfromlis)
{1, 2, 100, 50}

In [185]: print(set2)
{100, 10, 20, 30}
# объединить 2 множества...
In [202]: setfromlis.union(set2)
Out[202]: {1, 2, 10, 20, 30, 50, 100}
# ... или так
In [203]: setfromlis|set2
Out[203]: {1, 2, 10, 20, 30, 50, 100}
# пересечение множеств ...
In [204]: setfromlis.intersection(set2)
Out[204]: {100}
# ... или так
In [205]: setfromlis&set2
Out[205]: {100}

Булевы значения - Boolean - bool()

В питоне для значений True и False определён класс bool(). bool() - это подкласс класса int(). Иными словами, традиционно True - 1, False - 0 (но не совсем). Значения булева типа в python возвращают следующие операции:

  • Преобразование int float str и др:
    • False
      • bool(0) # int ноль = False
      • bool(0.0) # float ноль = False
      • bool('') # пустая строка или любой иной объект(str(),set(),list[],dict{},range(0))
      • bool(None) # пустое значение
      • not True # отрицание True
    • True
      • bool('everething_others') # любая непустая строка = True
      • bool(N) # любое ненулевое число
      • not False # отрицание False
  • Логические операции: not, and, or
  • Операции сравнения: >, < , <=, >=, ==, !=

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

ОперацияОписание
x or y
x and y
not x
# логические операции
In [236]: not False
Out[236]: True

In [237]: not True
Out[237]: False
# AND - И - вернет True, только если оба значение True
In [238]: True and False
Out[238]: False

In [239]: False and False
Out[239]: False

In [240]: True and True
Out[240]: True

In [241]: False and True
Out[241]: False
# Стоит помнить, если объекты при выполнении логической операции не в bool виде,
# то будет возвращено значение параметра, которое привело к False.
# При этом, если False значение на первом месте, то второе не проверяется (читай - не выполняется)
In [249]: a = 0

In [250]: b = 'ab'

In [251]: bool(a)
Out[251]: False

In [252]: bool(b)
Out[252]: True

In [253]: bool(a and b)
Out[253]: False

In [254]: a and b
Out[254]: 0

In [265]: c = ''

In [268]: bool(c)
Out[268]: False
# второе False значение - не проверяется и не возвращается
In [266]: a and c
Out[266]: 0
# второе False значение - не проверяется и не возвращается
In [267]: c and a
Out[267]: ''
# OR - ИЛИ - вернет False только если оба оператора False
# при не булевом формате, вернется, либо значение True (если True or False),
# либо последнее False (если False or False)
In [258]: True or True
Out[258]: True

In [259]: False or True
Out[259]: True

In [260]: True or False
Out[260]: True

In [261]: False or False
Out[261]: False

In [262]: a or b
Out[262]: 'ab'

In [263]: b or a
Out[263]: 'ab'

In [269]: a or c
Out[269]: ''

# операции сравнения
# тут все проще
In [222]: 2 < 3
Out[222]: True

In [223]: 3 < 2
Out[223]: False

In [224]: 3 > 2
Out[224]: True

In [225]: 3 < 2
Out[225]: False

In [226]: 2 >= 3
Out[226]: False

In [227]: 3 >= 3
Out[227]: True

In [228]: 2 <= 3
Out[228]: True

In [229]: 4 <= 3
Out[229]: False

In [230]: 3 == 3
Out[230]: True

In [231]: 3 == 2
Out[231]: False

In [232]: 2 != 3
Out[232]: True

In [234]: 'ab' == 'Ab'
Out[234]: False

In [235]: 'ab' == 'ab'
Out[235]: True

На этом на сегодня все. Спасибо большое УЦ Специалист (https://www.specialist.ru/course/python1-a) и Наталье Самойленко (https://pyneng.github.io). Вполне есть надежда, что в это году может быть больше статей.

С Уважением, Mc.Sim.


Другие материалы в категории coding


Теги: ,
Комментариев пока нет.

Написать комментарий