Основные типы объектов: числа и списки#

Программы на языке python могут быть разложены на модули, операторы, выражения и объекты по схеме ниже.

  1. Программы состоят из модулей;

  2. Модули содержат операторы;

  3. Операторы содержат выражения;

  4. Выражения создают и обрабатывают объекты;

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

В python всё является объектом#

В python всё — от булевых значений и чисел до функций, классов и файлов — представляется в виде объекта в смысле ООП. Это значит, что даже такие простые данные как целые числа хранятся упакованными в объект, у которого могут быть атрибуты и методы.

x = 42
print(x.bit_length())
6

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

1. Числа#

Числа — один из самых простых и понятных типов данных для компьютера, а по совместительству и один из самых простых типов объектов в python.

1.1. Целые числа. int#

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

a = 42 
b = 5
print("a = {}, b = {}".format(a, b))  # форматирование строки методом format
print(type(a))
a = 42, b = 5
<class 'int'>

Напомним, что в C/C++ 32-битные целые числа принимают значения в диапазоне от \(-2^{32} = -2,147,483,648\) до \(2^{32} - 1 = 2,147,483,647\). В python целые числа могут принимать произвольные значения, ограниченные только объемом оперативной памяти машины, на которой запускается код. Это очень удобно, так как не нужно заботиться о переполнении и нет необходимости определять пользовательские типы для обработки больших значений.

print(2 ** 1000)
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

1.2. Числа с плавающей точкой. float#

Числа с плавающей точкой реализованы по тому же стандарту, что и в C/C++ (IEEE 754), представлены 64-х битным типом float (соответствует double в C/C++), а значит и ведут себя абсолютно точно также.

print(f"a / b = {a / b}")
print(type(a / b))
a / b = 8.4
<class 'float'>
c = 3.1415
d = c ** .5
print(f"c = {c}, d = {d}")
print(f"d = {d:.2f}")                         # форматирование вывода f-строкой               
c = 3.1415, d = 1.772427713617681
d = 1.77

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

Также в python встроены комплексные числа, представленные типом complex.

e = complex(42, 13)
print(type(e))
<class 'complex'>

Для их записи в качестве мнимой единицы можно использовать строчную или прописную букву “j”.

f = 42 + 13j
g = 42 + 13J
print(e == f == g)
True

Все арифметические операторы работаю с комплексными числами корректно.

imaginary_unit = 1j
print(imaginary_unit**2)
(-1+0j)

Действительную и мнимую части комплексного числа можно узнать атрибутами imag и real соответственно.

print(f"{f.real=}, {f.imag=}")
f.real=42.0, f.imag=13.0

1.4. Булевый тип. bool#

Булевые значения True и False представляются типом данных bool.

flag = True
print(type(flag))
<class 'bool'>

На самом деле False соответствует целочисленный нуль, а True — единица.

print(f"True = {int(True)}")
print(f"False = {int(False)}")
print(isinstance(flag, int))                # True, т.е. булевые значения реализованы как целые числа
True = 1
False = 0
True

Сравнение чисел#

Получить булевое значение можно, например, сравнив числа на больше/меньше. Для сравнения чисел в python используются те же операторы, что и в C/C++:

  • ==”;

  • !=”;

  • <”;

  • >”;

  • <=”;

  • >=”.

print(13 < 42)
True

Булевые операторы.#

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

Так, например, логическое “И” представлено бинарным and.

print(False and False)
print(False and True)
print(True and False)
print(True and True)
False
False
False
True

Логическое “ИЛИ” — бинарным оператором or.

print(False or False)
print(False or True)
print(True or False)
print(True or True)
False
True
True
True

Логическое “НЕ” — унарным оператором not.

print(not False)
print(not True)
True
False

Приведение к bool#

Ноль приводятся к False, а числа отличные от нуля к True.

print("Нули: ", end="\t\t")
print(bool(0), bool(0.), bool(complex(0, 0)), sep=", ")
print("Не нули: ", end="\t")
print(bool(1), bool(1.), bool(complex(0, 1)), sep=", ")
Нули: 		False, False, False
Не нули: 	True, True, True

1.5. None#

В python есть специальный тип данных NoneType, который может принимать единственно возможное значение None.

null_variable = None
print(type(None))
<class 'NoneType'>

None всегда приводится к False.

bool(None)
False

2. Списки#

Первый контейнер, с которым мы познакомимся — список. Список (list) - наиболее близкий аналог к массиву из C/C++, если брать в расчет только встроенные типы. Существенным отличием является возможность хранения в одном и том же списке объекты разных типов.

В python ряд контейнеров обладают общими чертами. list — представитель группы контейнеров Sequence Types (последовательности). Последовательность означает, что элементы контейнера пронумерованы и к ним можно обращаться по индексу (zero-based, как и в C/C++ ).

Другие представители последовательностей в python:

  • кортежи tuple;

  • диапазоны range;

  • строки str;

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

l = [1, 3, 7]

print(l)
print(type(l))
[1, 3, 7]
<class 'list'>

Встроенная функция len позволяет узнать длину списка.

print(len(l))
3

Синтаксис получения элемента списка по его индексу напоминает C/C++.

print(l[1])                     # Обращение к элементу списка по смещению
print(l[0], l[-1])             
3
1 7

У списка есть встроенный метод сортировки list.sort(), который сортирует его на месте (in-place).

l = [42, 7, 13, -1, 123]

print(sorted(l))               # Функция sorted конструирует новый список
print(l) 
[-1, 7, 13, 42, 123]
[42, 7, 13, -1, 123]

Также есть функция sorted(), которая конструирует новый отсортированный список на основе своего аргумента (список или любой другой итерируемый объект).

l.sort()
print(l)
[-1, 7, 13, 42, 123]

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

l.append("a string")
print(l)
l.append(["строка внутри списка внутри списка"])
print(l)
[-1, 7, 13, 42, 123, 'a string']
[-1, 7, 13, 42, 123, 'a string', ['строка внутри списка внутри списка']]

Пустой список приводится к False. Любой не пустой список приводится к True. Иногда это используется для проверки на пустоту списка.

print(bool([]), bool([0]))
False True