Python: структуры данных
Списки (list)
Список (list) в Python представляет собой упорядоченную коллекцию элементов, т.е. вы храните последовательность элементов в списке. Вы можете представлять их как списсок покупок в магазине, но с той разницей, что в вашем списке покупок каждый элемент скорее всего будет в новой строке, а в Python — они разделяются запятыми.
Такой список элементов должен быть заключён в квадратные скобки. После того, как вы создали список — вы можете добавлять, удалять и выполнять поиск по элементам в нём.
Т.к. мы можем добавлять и удалять данные в списках — то они называются изменяемыми (mutable) типов данных.
Краткий обзор объектов и классов
Списки являются отличными примером использования объектов и классов. Когда мы используем переменную i и присваиваем ей значение, например целочисленное 5 — вы можете представлять себе это как создание объекта/интанса с именем i класса integer.
Класс так же может иметь определённый набор методов, т.е. функций, используемых только с этим классом, и которые могут быть использованы только после создания интанса класса.
Например — Python предоставляет метод append класса list, который позволяет добавить элемент в список. Так, mylist.append('item') добавит строку «item» к списку mylist.
Кроме того — класс может так же иметь поля/атрибуты, которые являются ничем иным, как переменными этого класса.
Пример списков в Python
Возьмём следующий скрипт:
#!/usr/bin/env python
shoplist = ['apple', 'mango', 'carrot', 'banana']
print('I have', len(shoplist), 'items to purchase.')
print('These items are:', end=' ')
for item in shoplist:
print(item, end=' ')
print('\nI also have to buy rice.')
shoplist.append('rice')
print('My shopping list is now', shoplist)
print('I will sort my list now')
shoplist.sort()
print('Sorted shopping list is', shoplist)
print('The first item I will buy is', shoplist[0])
olditem = shoplist[0]
del shoplist[0]
print('I bought the', olditem)
print('My shopping list is now', shoplist)Результат его выполнения:
Как это работает
Переменная shoplist представляет собой «список покупок». В ней мы храним строки — названия того, что требуется купить, но вы можете добавить в список любой тип объекта, включая числа и даже другие списки (вложенные списки):
>>> shoplist = ['apple', 'mango', 'carrot', 'banana'] >>> otherlist = ['item1', 'item2'] >>> shoplist.append(otherlist) >>> print(shoplist) ['apple', 'mango', 'carrot', 'banana', ['item1', 'item2']]
Кроме того — мы можем использовать цикл for..in для того, что бы получить все элементы списка:
>>> for i in shoplist: ... print(i) ... apple mango carrot banana ['item1', 'item2']
Кроме метода append() выше — мы можем использовать оператор del, что бы удалить элемент списка.
Например — удалить последний элемент (вложенный список otherlist, добавленный с помощью append() в конец списка):
>>> del shoplist[-1] >>> for i in shoplist: ... print(i) ... apple banana carrot mango
Мы так же использовали метод sort для сортировки элементов списка:
>>> shoplist.sort() >>> for i in shoplist: ... print(i) ... apple banana carrot mango
Кортежи (tuple)
Кортежи используются для хранения нескольких объектов. По сути кортежи схожи со списками, с той разницей что они не предоставляют такой функциональности, как списки. Главное их отличие — кортежи явлются неизменямым (immutable) типом данных.
Кортежи задаются через запятую и опционально — с добавлением круглых скобочек:
>>> tuple = 'item1', 'item2'
>>> type(tuple)
<class 'tuple'>
>>> tuple = ('item1', 'item2')
>>> type(tuple)
<class 'tuple'>Пример кортежей в Python
Рассмотрим такой скрипт:
#!/usr/bin/env python
# I would recommend always using parentheses
# to indicate start and end of tuple
# even though parentheses are optional.
# Explicit is better than implicit.
zoo = ('python', 'elephant', 'penguin')
print('Number of animals in the zoo is', len(zoo))
new_zoo = 'monkey', 'camel', zoo
print('Number of cages in the new zoo is', len(new_zoo))
print('All animals in new zoo are', new_zoo)
print('Animals brought from old zoo are', new_zoo[2])
print('Last animal brought from old zoo is', new_zoo[2][2])
print('Number of animals in the new zoo is',
len(new_zoo)-1+len(new_zoo[2]))Результат его выполнения:
Как это работает
Переменная zoo является кортежем элементов.
Мы можем использовать метод len() для получения длины кортежа, что свидельствуюет о том, что как и списки — кортежи являются последовательностями (см. ниже).
>>> zoo = ('python', 'elephant', 'penguin')
>>> len(zoo)
3По аналогии со списками — мы можем так же использовать вложенные кортежи:
>>> newnew_zoo = 'monkey', 'camel', zoo
>>> print(newnew_zoo)
('monkey', 'camel', ('python', 'elephant', 'penguin'))Как и со списками — мы можем использовать срезы (slice) для доступа к элементам кортежа. При этом помните, что нумерация элементов начинается с 0:
>>> print(newnew_zoo[0])
monkey
>>> print(newnew_zoo[-1])
('python', 'elephant', 'penguin')
>>> print(newnew_zoo[-1][0])
pythonСловари (dictionary)
Словарь представлояет собой что-то вроде «записной книги» — адрес человека зная только его имя: в словаре ключ (key) ассоциируется со значением (value).
Поните, что все ключи в одном словаре должны быть уникальными.
Кроме того — учтите, что для ключей вы должны использовать неизменяемый тип данных (например — строки), но при этом — доабвлять любой тип данных в значения.
Пара ключ:значение в словаре указываются с помощью нотации dict = {key1:value1, key2: valu2}.
Все ключи в словаре хранятся в неупорядоченном состоянии.
Словари являются объекатами класса dict.
Пример словаря в Python
Рассмотрим такой скрипт:
#!/usr/bin/env python
# 'ab' is short for 'a'ddress'b'ook
ab = {
'Swaroop': 'swaroop@swaroopch.com',
'Larry': 'larry@wall.org',
'Matsumoto': 'matz@ruby-lang.org',
'Spammer': 'spammer@hotmail.com'
}
print("Swaroop's address is", ab['Swaroop'])
# Deleting a key-value pair
del ab['Spammer']
print('\nThere are {} contacts in the address-book\n'.format(len(ab)))
for name, address in ab.items():
print('Contact {} at {}'.format(name, address))
# Adding a key-value pair
ab['Guido'] = 'guido@python.org'
if 'Guido' in ab:
print("\nGuido's address is", ab['Guido'])Результат его выполнения:
Как это работает
Мы создали словарь ab, после чего получаем доступ к значением по ключам:
>>> ab = {
... 'Swaroop': 'swaroop@swaroopch.com',
... 'Larry': 'larry@wall.org',
... 'Matsumoto': 'matz@ruby-lang.org',
... 'Spammer': 'spammer@hotmail.com'
... }
>>> print(ab['Swaroop'])
swaroop@swaroopch.comИспользуя уже знакомый оператор del — мы можем удалять пару ключ-значение, при этом достаточно знать только ключ:
>>> del ab['Swaroop']
>>> print(ab['Swaroop'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Swaroop'
>>> print(ab)
{'Larry': 'larry@wall.org', 'Matsumoto': 'matz@ruby-lang.org', 'Spammer': 'spammer@hotmail.com'}Далее — мы используем метод items(), который возвращает нам список кортежей, где каждый кортеж хранит пару ключ:значение:
>>> print(ab.items())
dict_items([('Larry', 'larry@wall.org'), ('Matsumoto', 'matz@ruby-lang.org'), ('Spammer', 'spammer@hotmail.com')])Более того — мы можем использовать цикл for..in, присваивая ключ в переменную name а значение — в address:
>>> for name, address in ab.items(): ... print(name, address) ... Larry larry@wall.org Matsumoto matz@ruby-lang.org Spammer spammer@hotmail.com
И так же мы может добfвить новую пару ключ:значение в словарь:
>>> print(ab['Guido']) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'Guido' >>> ab['Guido'] = 'guido@python.org' >>> print(ab['Guido']) guido@python.org
И проверять наличие ключа, используя оператор in:
>>> if 'Guido' in ab: ... print(ab['Guido']) ... guido@python.org
Последовательности (sequence)
Списки, кортежи и строки являются примерами последовательностей, но что такое последовательность?
Главной отличительной возможностью последовательностей является проверка членства (membership test), т.е. применение выражений in и not in, а так же использование операций индексирования (indexing operations), которые позволяют получать определённые элементы из последовательности.
Три типа последовательностей, упомянутых выше — списки, кортежи и строки, так же имеют возможность применения слайсинга (slicing), которая позволяет получить часть последовательности.
Пример последовательностей в Python
Рассмотрим такой скрипт:
#!/usr/bin/env python
shoplist = ['apple', 'mango', 'carrot', 'banana']
name = 'swaroop'
# Indexing or 'Subscription' operation #
print('Item 0 is', shoplist[0])
print('Item 1 is', shoplist[1])
print('Item 2 is', shoplist[2])
print('Item 3 is', shoplist[3])
print('Item -1 is', shoplist[-1])
print('Item -2 is', shoplist[-2])
print('Character 0 is', name[0])
# Slicing on a list #
print('Item 1 to 3 is', shoplist[1:3])
print('Item 2 to end is', shoplist[2:])
print('Item 1 to -1 is', shoplist[1:-1])
print('Item start to end is', shoplist[:])
# Slicing on a string #
print('characters 1 to 3 is', name[1:3])
print('characters 2 to end is', name[2:])
print('characters 1 to -1 is', name[1:-1])
print('characters start to end is', name[:])Результат его выполнения:
Как это работает
Индексирование
Сначала мы применяем индексы для получения элемента последовательности:
>>> shoplist = ['apple', 'mango', 'carrot', 'banana'] >>> print(shoplist[0]) apple
При этом помните, что индексы в Python начинаются с нуля, т.е. для получения первого элемента — используется индекс 0 ([0]), а для получения, например, четвёртого элемента — используется индекс 3 ([3]).
Кроме того — вы можете использовать отрицательные индексы — в таком сулчае отсчёт будет выполнен от конца последательности, т.е. [-1] вернёт последний элемент, [-2] — предпоследний и т.д.:
>>> print(shoplist[-1]) banana
Слайсинг
Операция слайсинга («среза«) выполняется с указанием имени последовательности и опционально — пары чисел (индексов), разделённых двоеточием:
>>> print(shoplist[1:3]) ['mango', 'carrot']
Вы можете пропустить первое или последнее значение. В таком случае Python выведет элементы от первого до заданного индекса, или наоборот:
>>> print(shoplist[:3]) ['apple', 'mango', 'carrot'] >>> print(shoplist[3:]) ['banana']
Либо не указывать их вообще:
>>> print(shoplist[:]) ['apple', 'mango', 'carrot', 'banana'] >>> print(shoplist) ['apple', 'mango', 'carrot', 'banana']
Как и с индексами — вы можете использовать отрицательные значения для получения среза:
>>> print(shoplist[:-1]) ['apple', 'mango', 'carrot'] >>> print(shoplist[-1:-1]) [] >>> print(shoplist[-1:]) ['banana']
Более того — допустимо указание третьего аргумента, который задаёт шаг среза (по умолчанию равен единице):
>>> print(shoplist[::2]) ['apple', 'carrot']
Множества (set)
Множества являются неупорядоченными коллекциями простых объектов, и используются в тех случаях, когда присутсвие объекта в коллекции важнее, чем порядок или количество вхождений этого элемента в одной коллекции.
Используя множества — вы можете использовать проверки членства, добавлять и удалять элементы, объединять их, выполнять проверку на принадлежность другому множеству и так далее. Элементом множества может являтся любой неизменяемый тип данных — числа, строки, кортежи.
Например:
>>> bri = set(['brazil', 'russia', 'india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
>>> bric = bri.copy()
>>> bric.add('china')
>>> bric.issuperset(bri)
True
>>> bri.remove('russia')
>>> bri & bric
{'india', 'brazil'}