Урок №21. Табличные величины (массивы).
Основное предназначение современных компьютеров — обработка большого количества данных. При этом надо как-то обращаться к каждой из тысяч (или даже миллионов) ячеек с данными. Очень сложно дать каждой ячейке собственное имя и при этом не запутаться. Из этой ситуации выходят так: дают имя не ячейке, а группе ячеек, в которой каждая ячейка имеет собственный номер. Такая область памяти называется массивом (или таблицей).
Массив — это группа переменных одного типа, расположенных в памяти рядом и имеющих общее имя. Каждая ячейка в массиве имеет уникальный номер (индекс).
Для работы с массивами нужно в первую очередь научиться:
- выделять память нужного размера под массив;
- записывать данные в нужную ячейку;
- читать данные из ячейки массива.
В языке Python нет такой структуры, как «массив». Вместо этого для хранения группы однотипных объектов используют списки (тип данных list).
Список в Python — это набор элементов, каждый из которых имеет свой номер (индекс). Нумерация всегда начинается с нуля (как в С-подобных языках), второй по счёту элемент имеет номер 1 и т. д. В отличие от обычных массивов в большинстве языков программирования список — это динамическая структура, его размер можно изменять во время выполнения программы (удалять и добавлять элементы), при этом все операции по управлению памятью берёт на себя транслятор.
Список можно создать перечислением элементов через запятую в квадратных скобках, например так:
А = [1, 3, 4, 23, 5]Списки можно «складывать» с помощью знака «+», например, показанный выше список можно было построить так:
А = [1, 3] + [ 4, 23] + [5]Сложение одинаковых списков заменяется умножением «*». Вот так создаётся список из 10 элементов, заполненный нулями:
А = [0] *10В более сложных случаях используют генераторы списков — выражения, напоминающие цикл, с помощью которых заполняются элементы вновь созданного списка:
А =[i for i in range(10) ]Как вы знаете, цикл for i in range (10) перебирает все значения i от 0 до 9. Выражение перед словом for (в данном случае — i) — это то, что записывается в очередной элемент списка для каждого i. В приведённом примере список заполняется значениями, которые последовательно принимает переменная i, т. е. получим такой список:
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]Такой же список можно получить, применив функцию list (создание списка) к данным, полученным с помощью функции range:
А = list (range(10))Для заполнения списка квадратами этих чисел можно использовать такой генератор:
А =[ i*i for i in range (10)]В конце записи генератора можно добавить условие отбора. В этом случае в список включаются лишь те из элементов, перебираемых в цикле, которые удовлетворяют этому условию.
Далее под выражением «массив» мы будем подразумевать «однотипные данные, хранящиеся в виде списка». Переменная i будет обозначать индекс элемента списка.
Часто в тестовых и учебных программах массив заполняют случайными числами. Это тоже можно сделать с помощью генератора:
from random import randint
A = [ randint(20, 100) for x in range (10)]
Здесь создаётся массив из 10 элементов и заполняется случайными числами из отрезка [20, 100]. Для этого используется функция randint, которая импортируется из модуля random.
Длина списка (количество элементов в нём) определяется с помощью функции lеn:
N = len(А)Проще всего добавить элемент в конец массива, для этого используется метод append:
А = [1, 2, 3]
х = 5
A.append(х+3) # получаем А = [1, 2, 3, 8]
Метод — это подпрограмма (процедура или функция), связанная с каким-то объектом. Чтобы вызвать метод, используют точечную запись: название метода записывают через точку после названия объекта.
Для того чтобы вставить элемент в любое место массива, применяется другой метод — insert. В параметрах сначала указывается номер нового элемента в массиве, а затем — его значение:
A = [1, 2, 3]
A.insert(1, 35) # получаем A=[1, 35, 2, 3]
В этом примере новый элемент встаёт на место А [ 1 ], а остальные элементы сдвигаются в конец массива.
Для удаления элемента с известным номером используется метод pop. Если номер не указан, удаляется последний элемент. Удалённый элемент возвращается как результат работы метода:
А = [1, 2, 3]
х = А.рор(1) # получаем А = [1, 3], х = 2
х = A.pop() # теперь А = [ 1 ] , х = 3
Элементы массива можно удалять не только по номеру, но и по значению. Для этого используется метод remove. Например, первый элемент, равный 99, удаляется так:
А = [1, 2, 99, 3, 99]
A.remove(99) # получаем А= [1, 2, 3, 99]
Далее во всех примерах мы будем считать, что в программе создан список А, в котором хранится массив из N однотипных элементов — целых чисел. Переменная i будет обозначать индекс элемента списка (массива).
Чтобы ввести значения элементов массива с клавиатуры, нужно использовать цикл:
for i in range(N):
print ("A[", i, "]=", sep = "", end = "")
A[i] = int(input())
В этом примере перед вводом очередного элемента массива на экран выводится подсказка. Например, при вводе 3-го элемента будет выведено А [ 3 ] =.
Если никакие подсказки нам не нужны, создать массив из N элементов и ввести их значения можно с помощью генератора списка:
А = [ int(input()) for i in range(N)]Здесь на каждом шаге цикла строка, введённая пользователем, преобразуется в целое число с помощью функции int, и это число добавляется к массиву.
Возможен ещё один вариант, когда весь массив вводится в одной строке. В этом случае строку, полученную от функции input, нужно «расщепить» на части с помощью метода split:
data = input()
s = data.split()
или сразу:
s = input().split()Например, если ввести строку «1 2 3 4 5», то после «расщепления» мы получим массив
["1", "2", "3", "4", "5"]Это массив символьных строк. Для того чтобы построить массив (список), состоящий из целых чисел, нужно применить к каждому элементу списка функцию int:
А = [ int(x) for х in s]Вместо генератора можно было использовать функцию mар:
А = list(mар(int, s))Такая запись означает «применить функцию int ко всем элементам списка s и составить из полученных чисел новый список (объект типа list)».
Теперь поговорим о выводе массива на экран. Самый простой способ — вывести массив как один объект:
print(А)В этом случае весь список берётся в квадратные скобки, и элементы разделяются запятыми:
[1, 12, 32, 14, 25]Вывести массив на экран можно и поэлементно:
for i in range(N):
print (A[i], end = " ")
После вывода каждого элемента ставится пробел (иначе все значения сольются в одну строку):
1 12 32 14 25Удобно записывать такой цикл несколько иначе:
for х in А:
print (х, end = " ")
Здесь не используется переменная-индекс i, а просто перебираются все элементы списка: на каждом шаге в переменную х заносится значение очередного элемента массива (в порядке возрастания индексов).
В языке Python есть ещё один способ вывести все элементы массива через пробел:
print(*А)Здесь знак «*» означает, что вместо одного объекта (массива) мы хотим получить его отдельные элементы, перечисленные через запятую.
Перебор элементов массива состоит в том, что мы в цикле просматриваем все элементы и, если нужно, выполняем с каждым из них некоторую операцию. Переменная цикла изменяется от О до N — 1, где N — количество элементов массива, т. е. в диапазоне range(N):
for i in range(N):
A[i] += 1
в этом примере все элементы массива А увеличиваются на 1.
Если массив изменять не нужно, для перебора его элементов удобнее всего использовать такой цикл:
for х in А:
...
Здесь вместо многоточия можно добавлять операторы, работающие с копией элемента, записанной в переменную х. Обратите внимание, что изменение переменной х в теле цикла не приведёт к изменению соответствующего элемента массива А.
Заметим, что для первой задачи (увеличить все элементы массива на 1) есть красивое решение в стиле Python, использующее генератор списка, который построит новый массив:
А = [х+1 for х in А]В цикле перебираются все элементы исходного массива, и в новый массив они попадают после увеличения на 1.
Во многих задачах требуется найти в массиве все элементы, удовлетворяющие заданному условию, и как-то их обработать. Простейшая из таких задач — подсчёт нужных элементов. Для решения этой задачи нужно ввести переменную-счётчик, начальное значение которой равно нулю. Далее в цикле просматриваем все элементы массива. Если для очередного элемента выполняется заданное условие, то увеличиваем счётчик на 1. На псевдокоде этот алгоритм выглядит так:
счётчик = О
for х in А:
if условие выполняется для х:
счётчик += 1
Предположим, что в массиве А записаны данные о росте игроков баскетбольной команды. Найдем количество игроков, рост которых больше 180 см, но меньше 190 см. В следующей программе используется переменная-счётчик count:
count = О
for x in A:
if 180 < x and x < 190:
count += 1
Теперь усложним задачу: требуется найти средний рост этих игроков. Для этого нужно дополнительно в отдельной переменной складывать все нужные значения, а после завершения цикла разделить эту сумму на количество. Начальное значение переменной summa, в которой накапливается сумма, тоже должно быть равно нулю.
count = 0
summa = 0
for х in А:
if 180 < х and x < 190:
count += 1
summa += x
print(summa/count)
Суммирование элементов массива — это очень распространённая операция, поэтому для суммирования элементов списка в Python существует встроенная функция sum:
print(sum(А))С её помощью можно решить предыдущую задачу более элегантно, в стиле языка Python: сначала выделить в дополнительный массив все нужные элементы, а затем разделить их сумму на количество (длину массива).
Для построения нового массива будем использовать генератор:
В = [х for х in A if l80<x and х < 190 ]Таким образом, мы отбираем в массив В те элементы из массива А, которые удовлетворяют этому условию. Теперь для вывода среднего роста выбранных игроков остается разделить сумму элементов нового массива на их количество:
print(sum(В)/len(В))