Упорядоченный список


Часто в программах требуется хранить различные списки данных, например, список городов, число выигранных очков в серии игр, или значения некоторой функции:

Москва

Санкт-Петербург

Самара

Казань

Тверь

1200

200

500

2100

100

0.5

0.55

0.6

0.4

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

[элемент1, элемент2, …, элементN]

Например, для хранения городов можно задать такой список:

lst = ["Москва", "Санкт-Петербург", "Тверь", "Казань"]

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

Здесь синей рамкой отмечен сам список, внутри которого располагаются элементы. Если мы посмотрим тип объекта, на который ссылается переменая lst:

type(lst)

то увидим значение «list». Это как раз и есть тип списка. То есть, через переменную lst мы можем работать со списком в целом, и первое, что нас здесь интересует: как обратиться к определенному элементу этого списка? Для этого используется такой синтаксис:

список[индекс]

Например,

lst[0]

lst[2]

Но, если мы укажем не существующий индекс:

lst[5]

то возникнет ошибка. Чтобы этого избежать нам надо знать значение последнего индекса. Для этого можно воспользоваться функцией

len(список)

которая возвращает число элементов в списке:

len(lst)

вернет значение 4. Но, так как индексы начинаются с нуля, то последний индекс будет равен:

lastIndex = len(lst) – 1

То есть, можно записать вот так:

lst[len(lst)-1]

но можно и проще, вот так:

lst[-1]

Этот пример показывает, что при отрицательных индексах, мы начинаем движение с конца списка и значение -1 дает самый последний элемент.

Далее, для перебора элементов списка в Python очень удобно использовать цикл for:

lst = ["Москва", "Санкт-Петербург", "Тверь", "Казань"]

for city in lst:

   print(city)

Смотрите, как это легко и просто делается! Конечно, мы можем распечатать весь контейнер целиком, просто записав:

print(lst)

Но здесь нет перебора всех элементов, а просто печать содержимого. Вернемся к циклу. Здесь переменная city будет ссылаться на элементы внутри списка lst. Давайте выведем в консоль дополнительно еще тип выводимого значения:

print(city, type(city))

Увидим везде строковый тип str. Но раз city ссылается на элементы списка, можно ли их изменить, присвоив этой переменной другое значение?

city = "новое значение"

Если мы теперь выведем список lst в консоль:

print(lst)

то окажется, что список не изменился. Почему? Дело в том, что когда мы присваиваем переменной новое значение, то она просто начинает ссылаться на новый объект и на состоянии списка это никак не сказывается.

Вот этот момент работы переменных как ссылок на объекты всегда следует учитывать при программировании на Python. Также следует помнить, что в этом языке типы данных делятся на два класса: изменяемые и неизменяемые. Все предыдущие типы, что мы проходили на прошлых занятиях относились к неизменяемым. Это были:

числа, булевые значения, строки

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

список[индекс] = значение

Например, так:

lst[0] = "Самара"

Теперь первый элемент не «Москва», а «Самара». В действительности, здесь произошло следующее:

Мы поменяли значение ссылки lst[0] первого элемента списка. Изначально она ссылалась на объект «Москва», а затем, стала ссылаться на объект «Самара». Прежний объект автоматически удаляется сборщиком мусора. Вот так происходит изменение элементов списка, то есть, меняются значения ссылок на новые объекты.

Теперь вернемся к вопросу изменения элементов списка внутри цикла for. Предположим, у нас имеется список чисел:

digs = [-1, 0, 5, 3, 2]

и в цикле мы хотим его изменить на их квадраты. Для этого запишем цикл в таком виде:

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 элементов? Для этого можно воспользоваться такой конструкцией, например:

A = [0]*1000

создает список из 1000 элементов со значением 0. Фактически, мы здесь сначала создали список из одного нулевого элемента, а затем, размножили его до тысячи. Или, можно сделать так:

A = ["none"]*100

Получим 100 элементов со строкой «none». И так далее. Кстати, если требуется создать пустой список, то это будет так:

A = []

Ну хорошо, есть у нас список из 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]]

Причем, его длина

len(t)

будет равна 5, т.к. последний элемент – вложенный список здесь воспринимается как один отдельный элемент. И этот пример показывает как можно создавать двумерные списки:

A = [[1,2,3], [4,5,6], [7,8,9]]

Для доступа к конкретному числу следует сначала обратиться к первому списку:

A[1]

а, затем, ко второму:

A[1][0]

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

A[1][2] = -1

Далее, списки можно объединять друг с другом, используя оператор +:

[1,2,3] + ["Москва", "Тверь"]

Используя этот оператор, можно добавлять новые элементы к списку:

digs = [1,2,3,4]

digs = digs + [5]

digs += [6]

или в начало:

digs = ["числа"]+digs

И здесь обратите внимание, что мы объединяем именно списки, то есть, вот такая запись:

digs = digs+3

приведет к ошибке, т.к. 3 – это число, а не список.

Следующий оператор:

3 in digs

возвращает True, если элемент, записанный слева, присутствует в списке, указанный справа. Иначе, значение False:

-1 in digs

Или, можно делать так:

[1,2,3] in A

То есть, в качестве элемента может быть любой тип данных.

Следующие две полезные функции:

digs = [1,2,3,4]

max(digs)

min(digs)

находят минимальное или максимальное числовое значение. И если в списке имеется не числовой элемент:

digs += "a"

то эти функции приводят к ошибкам.

Также можно вычислять сумму элементов числового списка:

d = [1,2,3,4]

sum(d)

выполнять сортировку чисел по возрастанию:

d = [-1, 0, 5, 3, 2, 5]

sorted(d)

или, по убыванию:

sorted(d, reverse=True)

Эта функция возвращает новый объект-список, прежний d остается без изменений.

Наконец, можно сравнивать списки между собой:

[1,2,3] == [1,2,3]

[1,2,3] != [1,2,3]

[1,2,3] > [1,2,3]

В последнем сравнении получим False, т.к. списки равны, но если записать так:

[10,2,3] > [1,2,3]

то первый список будет больше второго. Здесь сравнение больше, меньше выполняется по тому же принципу, что и у строк: перебираются последовательно элементы, и если текущий элемент первого списка больше соответствующего элемента второго списка, то первый список больше второго. И аналогично, при сравнении меньше:

[10,2,3] < [1,2,3]

Все эти сравнения работают с однотипными данными:

[1,2, "abc"] > [1,2, "abc"]

сработает корректно, а вот так:

[1,2,3] > [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.

icon