Как стать автором
Обновить

Осваиваем Python. Унция 1. Типы данных.

Время на прочтение6 мин
Количество просмотров80K
image
Продолжаю своё начинание. Данная статья является логическим продолжением первой. Было приятно читать ваши комментарии. Я надеялся, что данный цикл статей окажется для кого-то полезным, но совершенно не предполагал, что заинтересовавшихся будет довольно большое количество. Это заставляет относится к делу серьёзнее и ответственнее.
Без лишних слов, сразу к делу.


Как было сказано ранее, практически всё с чем мы имеем дело, программируя на питоне — это объекты. Типы объектов могут быть либо встроенными, либо описанные программистом с помощью классов. В этой статье речь пойдёт о встроенных типах объектов. Они из себя представляют:
  • Числа
  • Строки
  • Кортежи
  • Списки
  • Словари
  • Множества


Числа, строки и кортежи



Причина того, что эти типы оказались сведёнными в один раздел, кроется в одном очень важном моменте. Без понимания которого можно допустить трудно обнаруживаемые ошибки. Дело в том, что данные типы в отличии от списков и словарей являются неизменяемыми объектами. Т.е. создав их однажды — изменить их значение не представляется возможным. Возникает справедливый вопрос: каким тогда образом работают следующие инструкции?

>>> x = 2
>>> x
2
>>> x = 3
>>> x
3
>>> x = 'string'
>>> x
'string'


Инструкция x = 2 создаёт числовой объект со значением 2 и присваивает ссылку на этот объект переменной x. Далее инструкция x = 3 создаёт новый числовой объект со значением 3 и присваивает ссылку на него переменной x. А объект со значением 2 удаляется из памяти автоматическим сборщиком мусора т.к. была потеряна последняя ссылка на этот объект.
Благодаря этому справедливо следующее:

>>> x = y = 3 # переменные x и y содержат одну и ту же ссылку на объект 3
>>> x = 2 # переменная x теперь содержит ссылку на другой объект 2
>>> x
2
>>> y # y по-прежнему ссылается на объект 3
3


В тему будет упомянуть про оператор is. Этот оператор возвращает значение True, когда слева и справа от него находятся переменные содержащие указатели на один и тот же объект. Возникает вопрос о странном поведении этого оператора:
>>> x = 2
>>> y = 2 # создано два разных объекта
>>> x is y # по идее должно быть возвращено значение False
True


Здесь дело в кэширующих внутренних механизмах самого интерпретатора. Для оптимизации скорости выполнения при объявлении числового или короткого строкового объекта — в кэше создаётся пара ссылка и значение. И в дальнейшем при объявлении такого же объекта — не создаётся новый объект, а используется уже созданный. Напрашивается вывод о несостоятельности использования оператора is для числовых и строковых типов данных.

Дальше всё просто!
Типы числовых литералов:
  • целые числа неограниченной длины — интерпретатор сам определит необходимость использования объектов неограниченной длины и сделает необходимые преобразования. Более нет необходимости следить за переполнениями.
  • Числа с плавающей точкой
  • восьмеричные и шестнадцатеричные числа
  • комплексные числа

Некоторые операции над числами:

>>> print 2 ** 150 # 2 в степени 150
1427247692705959881058285969449495136382746624
>>> print int(5.89),round(5.89),round(5.89,1) # округление вниз, вверх, с точностью до 1 знака
5 6.0 5.9
>>> import math
>>> math.pi
3.1415926535897931
>>> print math.sin(math.pi/2)
1.0
>>> import random
>>> random.randint(1,100) # случайное целое число в диапазоне от 1 до 100
19


Строки:

Строки в апострофах и в кавычках — это одно и то же
Строки в тройных кавычках — в тройные кавычки можно заключить целый блок строк, например целиком HTML или XML документ.
Неформатированные строки — строки вида r«\n\t» — последовательности в такой строке не будут заменены на спец. Символы
Строки символов юникода — u'string' # теряет актуальность в версии 3.0 подробнее об изменениях 3.0

Базовые операции над строками:

>>> print str(len('string'))*3 # len() — возвращает количество символов в строке
666 # * — перегруженый оператор, делающий повтор строки указанное число раз
>>> 'r' in 'string' # оператор in возвращает True если подстрока найдена в строке
True
>>> 'string'.replace('r','') # замена одной подстроки на другую
'sting'
>>> 'string'.find('ri') # возвращает номер смещения искомой подстроки
2
>>> 'a,b,c'.split(',') # функция разделения на подстроки по указанному символу или подстроке
['a', 'b', 'c']
Более полную информацию о строковых методах можно получить, введя в интерактивном режиме команду help(str).
Так же строки уже были описаны моим будущим соавтором этого цикла статей тут

Индексирование, выборка и срезы последовательностей данных.


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

>>> 'string'[1]
't'
>>> 'string'[-2] # второй элемент с конца строки
'n'


Срез — достаточно мощный инструмент выборки данных из последовательностей, который используется не только в строках но и в коллекциях, речь о которых пойдёт в этой статье чуть ниже.
Общий вид:
S[i:j:h], где S — строка, i — значение смещения, левая граница (включительно), j — значение смещения, правая граница (она не входит в срез), h — значение шага.
Примеры:

>>> 'string'[0:4]
'stri'
>>> 'string'[:-2]
'stri'
>>> 'string'[0:5:2]
'srn'
>>> 'string'[0:5:-2]
'nrs'

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

Кортежи


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

Списки и словари



Списки и словари являются изменяемыми встроенными типами данных. А это значит, если возвращаться к тому с чего мы начали разговор, что, если создать список Y, затем сделать присваивание X=Y, а затем изменить X, то Y тоже изменится. За этим нужно внимательно следить! Для того, чтобы этого не происходило, необходимо создать новый объект эквивалентный исходному, например, так: X=Y[:]
Иллюстрация:

>>> M = L = range(2,12,3)
>>> print M,L
[2, 5, 8, 11] [2, 5, 8, 11]
>>> L[2] = 112
>>> print M,L
[2, 5, 112, 11] [2, 5, 112, 11]
>>> M = L[:]
>>> L[2] = 0
>>> print M,L
[2, 5, 112, 11] [2, 5, 0, 11]


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

Списки — потрясающе гибкий инструмент, представляющий из себя упорядоченную коллекцию элементов, который может включать в себя какие угодно объекты с каким угодно уровнем вложенности.
Словарь — является неупорядоченной коллекцией объектов, доступ к элементам которой предоставляется не с помощью смещения, а с помощью ключа.
За основами синтаксиса так же можно перейти к статье clega
Здесь я лишь внесу некоторые дополнения и замечания по использованию словарей:
  • операции над последовательностями неприменимы к словарям т.к. словари — это не последовательность, а отображение.
  • Ключи не обязательно должны быть строками. В роли ключей могут выступать любые неизменяемые объекты. Т.е. если рассматривать встроенные типы данных, то — это числа, строки и кортежи. Ясно, что при использования чисел, словарь превращается в подобие списка, однако, остаётся при этом неупорядоченным. Используя в качестве ключа кортежи, появляется возможность использовать составные ключи. Экземпляры пользовательских классов так же могут выступать в качестве ключей при условии, что они реализуют определённые методы указывающие интерпретатору на то, что объект является неизменяемым.


Множества



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

>>> M = set('habrahabr')
>>> L = set(['h','a','h','a'])
>>> M, L
(set(['a', 'h', 'r', 'b']), set(['a', 'h']))
>>> M & L
set(['a', 'h'])
>>> M | L
set(['a', 'r', 'h', 'b'])
>>> M - L
set(['r', 'b'])
>>> bool(M - L)
True
>>> pusto = set()
>>> bool(pusto)
False


Элементами множества могут стать любые неизменяемые объекты.
После того, как мы проделали определённые операции над множествами — их можно разместить обратно в список, например, так:

>>> S = []
>>> for i in M - L:
... S.append(i)
...
>>> S
['r', 'b']


На этом всё на сегодня.
Пользуясь терминологией Радио-Т хочется задать вопрос :) Куда подкрутить градус гиковости, по вашему мнению? Если вверх, то на мой взгляд, циклы и ветвления стоит раскрыть только с точки зрения особенностей присущих Python.
Спасибо за внимание! Мы продолжим :)
Теги:
Хабы:
Всего голосов 54: ↑45 и ↓9+36
Комментарии55

Публикации