Часто в
программах требуется хранить различные списки данных, например, список городов,
число выигранных очков в серии игр, или значения некоторой функции:
Москва
Санкт-Петербург
Самара
Казань
Тверь
|
1200
200
500
2100
100
|
0.5
0.55
0.6
0.4
|
Все это можно
представить в виде упорядоченно списка, который в Python задается с
помощью оператора квадратных скобок:
[элемент1,
элемент2, …, элементN]
Например, для
хранения городов можно задать такой список:
lst = ["Москва", "Санкт-Петербург", "Тверь", "Казань"]
И он будет
упорядоченный, то есть, каждому элементу здесь соответствует свой порядковый
индекс, начиная с нулевого:
Здесь синей
рамкой отмечен сам список, внутри которого располагаются элементы. Если мы
посмотрим тип объекта, на который ссылается переменая lst:
то увидим
значение «list». Это как раз и
есть тип списка. То есть, через переменную lst мы можем
работать со списком в целом, и первое, что нас здесь интересует: как обратиться
к определенному элементу этого списка? Для этого используется такой синтаксис:
список[индекс]
Например,
Но, если мы
укажем не существующий индекс:
то возникнет
ошибка. Чтобы этого избежать нам надо знать значение последнего индекса. Для
этого можно воспользоваться функцией
len(список)
которая
возвращает число элементов в списке:
вернет значение
4. Но, так как индексы начинаются с нуля, то последний индекс будет равен:
lastIndex
= len(lst) – 1
То есть, можно
записать вот так:
но можно и
проще, вот так:
Этот пример
показывает, что при отрицательных индексах, мы начинаем движение с конца списка
и значение -1 дает самый последний элемент.
Далее, для
перебора элементов списка в Python очень удобно использовать цикл for:
lst = ["Москва", "Санкт-Петербург", "Тверь", "Казань"]
for city in lst:
print(city)
Смотрите, как
это легко и просто делается! Конечно, мы можем распечатать весь контейнер
целиком, просто записав:
Но здесь нет
перебора всех элементов, а просто печать содержимого. Вернемся к циклу. Здесь
переменная city будет ссылаться
на элементы внутри списка lst. Давайте выведем в консоль
дополнительно еще тип выводимого значения:
Увидим везде
строковый тип str. Но раз city ссылается на
элементы списка, можно ли их изменить, присвоив этой переменной другое значение?
Если мы теперь
выведем список lst в консоль:
то окажется, что
список не изменился. Почему? Дело в том, что когда мы присваиваем переменной
новое значение, то она просто начинает ссылаться на новый объект и на состоянии
списка это никак не сказывается.
Вот этот момент
работы переменных как ссылок на объекты всегда следует учитывать при
программировании на Python. Также следует помнить, что в этом
языке типы данных делятся на два класса: изменяемые и неизменяемые.
Все предыдущие типы, что мы проходили на прошлых занятиях относились к
неизменяемым. Это были:
числа, булевые значения, строки
Но вот список list относится к
изменяемым типам, то есть, мы можем изменить его состояние, не создавая нового
объекта. В самом простом случае мы можем воспользоваться таким синтаксисом:
список[индекс] =
значение
Например, так:
Теперь первый
элемент не «Москва», а «Самара». В действительности, здесь произошло следующее:
Мы поменяли
значение ссылки lst[0] первого элемента списка. Изначально она
ссылалась на объект «Москва», а затем, стала ссылаться на объект «Самара».
Прежний объект автоматически удаляется сборщиком мусора. Вот так происходит
изменение элементов списка, то есть, меняются значения ссылок на новые объекты.
Теперь вернемся
к вопросу изменения элементов списка внутри цикла for. Предположим, у
нас имеется список чисел:
и в цикле мы
хотим его изменить на их квадраты. Для этого запишем цикл в таком виде:
digs = [-1, 0, 5, 3, 2]
for x in range(5):
digs[x] **= 2 #digs[x] = digs[x]**2
print(digs)
Или, чтобы не
указывать конкретное число в функции range, ее можно
переписать так:
for x in range(len(digs)):
И программа
будет работать со списком произвольной длины.
Во всех наших
примерах мы создавали списки небольшой длины и потому могли их запросто
записать в программе. Но что если требуется создать список размерностью в 100
или 1000 элементов? Для этого можно воспользоваться такой конструкцией,
например:
создает список
из 1000 элементов со значением 0. Фактически, мы здесь сначала создали список
из одного нулевого элемента, а затем, размножили его до тысячи. Или, можно
сделать так:
Получим 100
элементов со строкой «none». И так далее. Кстати, если требуется
создать пустой список, то это будет так:
Ну хорошо, есть
у нас список из 100 или 1000 или другого числа элементов. Но как нам теперь с
ним работать, например, занести туда какие-либо данные. Для наглядности, предположим,
пользователь вводит N чисел с клавиатуры (N<100) и пока
он вводит положительные значения, мы их добавляем в список. Как только он ввел
какое-либо отрицательное число, считывание прекращается и мы вычисляем среднее
арифметическое введенных значений. Это можно реализовать так:
digs = [0]*100
N = 0; x = 0
while x >= 0:
x = int(input("Введите целое число: "))
digs[N] = x
N += 1
S = 0
for x in range(N):
S += digs[x]
S = S/N;
print("S = %f, N = %d"%(S, N))
Теперь, когда мы
в целом познакомились со списками, отметим следующие моменты. Список может
состоять из произвольных данных, например:
t = ["строка", 5, 5.7, True, [1,2,3]]
Причем, его
длина
будет равна 5,
т.к. последний элемент – вложенный список здесь воспринимается как один
отдельный элемент. И этот пример показывает как можно создавать двумерные
списки:
A = [[1,2,3], [4,5,6], [7,8,9]]
Для доступа к
конкретному числу следует сначала обратиться к первому списку:
а, затем, ко
второму:
Получим значение
4. С этими списками можно выполнять все те же самые операции, о которых мы
говорили ранее, например, изменить значение:
Далее, списки
можно объединять друг с другом, используя оператор +:
[1,2,3] + ["Москва", "Тверь"]
Используя этот
оператор, можно добавлять новые элементы к списку:
digs = [1,2,3,4]
digs = digs + [5]
digs += [6]
или в начало:
И здесь обратите
внимание, что мы объединяем именно списки, то есть, вот такая запись:
приведет к
ошибке, т.к. 3 – это число, а не список.
Следующий
оператор:
возвращает True, если элемент,
записанный слева, присутствует в списке, указанный справа. Иначе, значение False:
Или, можно
делать так:
То есть, в
качестве элемента может быть любой тип данных.
Следующие две
полезные функции:
digs = [1,2,3,4]
max(digs)
min(digs)
находят
минимальное или максимальное числовое значение. И если в списке имеется не
числовой элемент:
то эти функции
приводят к ошибкам.
Также можно
вычислять сумму элементов числового списка:
выполнять
сортировку чисел по возрастанию:
d = [-1, 0, 5, 3, 2, 5]
sorted(d)
или, по убыванию:
Эта функция
возвращает новый объект-список, прежний d остается без
изменений.
Наконец, можно
сравнивать списки между собой:
[1,2,3] == [1,2,3]
[1,2,3] != [1,2,3]
[1,2,3] > [1,2,3]
В последнем
сравнении получим False, т.к. списки равны, но если записать
так:
то первый список
будет больше второго. Здесь сравнение больше, меньше выполняется по тому же
принципу, что и у строк: перебираются последовательно элементы, и если текущий
элемент первого списка больше соответствующего элемента второго списка, то
первый список больше второго. И аналогично, при сравнении меньше:
Все эти
сравнения работают с однотипными данными:
[1,2, "abc"] > [1,2, "abc"]
сработает
корректно, а вот так:
Произойдет
ошибка, т.к. число 3 не может быть сравнено со строкой «abc».
Задания для самопроверки
1. Дан список [-1,
0, 5, 3, 2]. Необходимо изменить его, увеличив каждое значение на 7.2.
2. Пользователь
вводит с клавиатуры N значений (строки или числа). На их основе
сформировать список, состоящий из продублированных элементов. (Например, из
значений 1, 5, "abc" формируется список [1, 1, 5, 5,
"abc", "abc"]).
3. Написать
программу сложения двух матриц:
4. Пользователь
вводит N значений в
список. Необходимо проверить: было ли введено число 5.