Основы программирования в Python

Алла Тамбовцева, НИУ ВШЭ

Данный ноутбук основан на лекции Щурова И.В., курс «Программирование на языке Python для сбора и анализа данных» (НИУ ВШЭ).

Введение в списки и цикл for

Знакомство со списками

Создадим список значений возраста респондентов, список age:

In [1]:
age = [23, 25, 32, 48, 19]  # возраст
age
Out[1]:
[23, 25, 32, 48, 19]

Элементы списка перечисляются в квадратных скобках через запятую.

Можем создать список имен name, полностью состоящий из строк:

In [2]:
name = ["Анна", "Виктор", "Дмитрий", "Алёна", "Павел"] # имена

А можем создать смешанный список – список, состоящий из элементов разных типов. Представим, что не очень сознательный исследователь закодировал пропущенные значения в списке текстом, написал "нет ответа":

In [3]:
mix = [23, 25, "нет ответа", 32, "нет ответа"] # все вместе

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

In [4]:
type(mix)
Out[4]:
list

Для тех, кто работал в R: векторы в R похожи на списки в Python. Но есть важное отличие: векторы в R могут содержать только элементы одного типа. Если типов несколько, один тип вытесняет другой. В R, вектор, содержащий как числа, так и строки, превратился бы в текстовый вектор – вектор типа character. Например, mix в R выглядел бы так:

"23", "25", "нет ответа", "32", "нет ответа"

У списка всегда есть длина – количество элементов в нем. Длина определяется с помощью функции len().

In [5]:
len(age)  # пять элементов
Out[5]:
5

Для тех, кто привык к R: просто len, не length!

Если список пустой, то, как несложно догадаться, его длина равна нулю:

In [6]:
empty = []
len(empty)
Out[6]:
0

Раз список состоит из элементов, к ним можно обратиться по отдельности. Главное, нужно помнить, что нумерация в Python начинается с нуля, а не с единицы. Существует несколько обоснований, почему это так, с одним из них мы познакомимся чуть позже, когда будем обсуждать срезы (slices).

In [7]:
age[0]  # первый элемент age
Out[7]:
23

Порядковый номер элемента в списке называется индексом. Далее, чтобы не путаться, будем разделять термины: порядковые числительные останутся для обозначения номера элемента в нашем обычном понимании, а индексы – для обозначения номера элемента в Python. Например, если нас будет интересовать элемент 25 из списка age, мы можем сказать, что нас интересует второй элемент или элемент с индексом 1:

In [8]:
print(age)
print(age[1])
[23, 25, 32, 48, 19]
25

Если элемента с интересующим нас индексом в списке нет, Python выдаст ошибку, а точнее, исключение, IndexError.

In [9]:
age[7]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-9-979e3832d406> in <module>
----> 1 age[7]

IndexError: list index out of range

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

In [10]:
age[len(age) - 1]  # последний элемент - 19
Out[10]:
19

Конечно, в том, что нумерация элементов в списке начинается с нуля, есть некоторое неудобство – индекс последнего элемента не совпадает с длиной списка. Но, на самом деле, обращаться к последнему элементу списка можно и по-другому: считать элементы с конца!

In [11]:
age[-1] # последний элемент - он же первый с конца
Out[11]:
19

Отрицательные индексы элементов в Python – абсолютно нормальная вещь. Можем так же получить второй элемент с конца:

In [12]:
age[-2]
Out[12]:
48

Цикл for

Раз есть списки, хочется научиться «пробегаться» по их элементам. Например, выводить на экран не весь список age сразу, а постепенно, каждый элемент с новой строчки. Для этого есть циклы. Рассмотрим цикл for.

In [13]:
for i in age:
    print(i)
23
25
32
48
19

Как устроен цикл выше? Кодом выше мы доносим до Python мысль:

  • пробегайся по всем элементам списка age (for i in age);
  • выводи каждый элемент на экран (print(i)).

Вообще любой цикл for имеет такую структуру: сначала указывается, по каким значениям нужно итерировать «пробегаться», а потом, что нужно делать. Действия, которые нужно выполнить в цикле, указываются после двоеточия в for – эта часть назвается телом цикла.

Буквы в конструкции for могут быть любые, совсем необязательно брать букву i. Python сам поймет, что мы имеем в виду, запуская цикл.

В качестве еще одного примера давайте для каждого элемента списка выведем на экран сообщение вида:

x^2 – квадрат числа x.
In [14]:
# вместо i напишем a
for a in age:
    print(a ** 2, "– квадрат числа", a)
529 – квадрат числа 23
625 – квадрат числа 25
1024 – квадрат числа 32
2304 – квадрат числа 48
361 – квадрат числа 19

Теперь, используя цикл и специальный метод .append(), создадим новый список на основе старого – дополним пустой список преобразованными элементами старого списка. Метод .append() работает просто: он приписывает элемент в конец списка. Например, так:

In [16]:
print(age)  # до
age.append(76)
print(age)  # после
[23, 25, 32, 48, 19]
[23, 25, 32, 48, 19, 76]

Теперь создадим на основе старого списка age список age2 с квадратами значений возраста:

In [17]:
age2 = []  # пока пустой список
for a in age:
    age2.append(a ** 2)
age2  # сработало!
Out[17]:
[529, 625, 1024, 2304, 361, 5776]

Конечно, циклы нужны не только для того, чтобы работать со списками. С помощью циклом можно решить любую задачу, которая требует повторения одинаковых действий. Вспомним задачу с семинара про питона, который греется на солнышке и каждый день увеличивает время пребывания на солнце. Тогда мы решали эту задачу, перезапуская ячейку с кодом несколько раз. Теперь воспользуемся циклом.

In [18]:
# создадим список с номерами дней

days = [2, 3, 4, 5, 6, 7, 8, 9 , 10]

# начальное значение времени, которое питон проводит на солнце

time = 1

print(1, time)

# теперь будем изменять значение time в цикле
# и выводить на экран номер дня и время

for d in days:
    time = time + 3
    print(d, time)
1 1
2 4
3 7
4 10
5 13
6 16
7 19
8 22
9 25
10 28