Списки

На прошлом занятии

  • оператор []
  • цикл while
  • цикл for
  • функция range()
  • функция enumerate
  • оператор break
  • оператор continue

План этого занятия

  • Списки
  • Индексы и срезы
  • Вложенные циклы

Списки

Список (list) - упорядоченная изменяемая коллекация элементов различных типов. Почти как массивы, но вообще ни разу не массивы. Элементы в списке могут быть различны типов и менять состав элементов списка можно когда угодно и как угодно (в отличии от массивов).

Создание списка

Чтобы использовать списки, их нужно сначала создать. Создать список можно несколькими способами. Например, можно обработать любой итерируемый (по которому можно пробежаться, используя цикл for) объект (например, строку) встроенной функцией list():

>>> list('привет')
['п', 'р', 'и', 'в', 'е', 'т']

Или же использовать встроенный в питон литерал, с первого взгляда похожий на оператор []:

>>> guests = ['Вася', 'Татуся', 'Пётр Яковлевич', 'мама']  # список строк
>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9]  # список чисел
>>> empty_list = []  # а этот список абсолютно пуст
>>> mixed_list = ['Вася', 45, True]  # в одном списке могут храниться элементы разных типов

Более того, список может содержать другие списки:

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

Как видно из примеров, список может содержать любое количество элементов любого типа или не содержать ничего.

Вставка элементов в список

Самая частая операция после [] (получение элемента списка по индексу) - это операция вставки чего-либо в список. Называется она .append(). Не нужно долго искать в словаре чтобы понять, как это переводится.

Только .append() это не отдельная функция, как например len(). Это так называемый метод списка. Смотрим как это работает:

>>> list_of_wishes = []  # Список моих желаний, когда меня спращивают, что я хочу на НГ
>>> list_of_wishes.append('iPhone X')  # После минутный раздумий
>>> print(list_of_wishes)
['iPhone X']  # мой список желаний 1 января

Синтаксис вызова методов списка такой: <НАЗВАНИЕ СПИСКА> <ТОЧКА> <НАЗВАНИЕ МЕТОДА> <СПИСОК АРГУМЕНТОВ В КРУГЛЫХ СКОБКАХ>

Или: some_list.append(False)

Понимание этого нам еще пригодится в одном миллионе мест, при изучении питона.

Другие методы списка

Помимо .append() у списка еще много методов. Вот некоторые из них (не все):

Название метода Описание
.extend(another_list) Расширяет список, добавляя в конец все элементы списка another_list
.insert(i, x) Вставляет в i-ую позицию в списке значение x
.remove(x) Удаляет первый элемент в списке, имеющий значение x
.clear() Очищает список

Вот такое работает метод .extend():

>>> first = [1, 2, 3]
>>> second = [5, 6, 7]
>>> first.extend(second)
>>> print(len(first))
6
>>> print(first)
[1, 2, 3, 5, 6, 7]

Метод .extend() изменяет изначальный список first, а не создает новый. С этим нужно быть внимательными!

Создать новый список из двух старых поможет оператор +:

>>> sweet = ['конфета', 'шоколадка']
>>> salty = ['крекер', 'сухарик']
>>> basket = sweet + salty
>>> print(basket)
['конфета', 'шоколадка', 'крекер', 'сухарик']

Вот тут можно посмотреть все методы списков и что они делают - https://pythoner.name/list-methods

Индексы и срезы

Индексы

Главное о списках:

  • их элементы нумеруются (“индексируются”) слева направо
  • счёт начинается с нуля (0)

К элементам списка, как и к символам в строке можно обращаться по их индексам:

>>> list_of_wishes = ['iPhone', 'MacBook', 'Свитшот']
>>> print(list_of_wishes[1])
'MacBook'

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

>>> my_purchases = ['Сыр', 'Масло', 'Кофе', 'Круассаны'] # Мои покупки за последнее время
>>> print(my_purchases[-1]) # Моя последняя покупка
'Круассаны'

Вопрос: как выбрать последний элемент списка не используя индекс -1?

Помимо последнего можно выбирать и предпоследний элемент:

>>> my_purchases = ['Сыр', 'Масло', 'Кофе', 'Круассаны']
>>> print(my_purchases[-2])
'Кофе'

Главное не переборщить:

>>> my_purchases = ['Сыр', 'Масло', 'Кофе', 'Круассаны']
>>> print(my_purchases[-20])
IndexError: list index out of range

Срезы

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

>>> list_of_chars = list('Вячеслав')
>>> print(list_of_chars)
['В', 'я', 'ч', 'е', 'с', 'л', 'а', 'в']
>>> print(list_of_chars[1:]) # Взять все символы имени, кроме первого
['я', 'ч', 'е', 'с', 'л', 'а', 'в']
>>> list_of_chars = list('Вячеслав')
>>> print(list_of_chars[-3:]) # последние 3 символа
['л', 'а', 'в']
>>> list_of_chars = list('Вячеслав')
>>> print(list_of_chars[2:5])
['ч', 'е', 'с']

Общий синтаксис срезов: list[START:END:STEP]

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

>>> list_of_chars = list('Вячеслав')
>>> print(list_of_chars[1::2]) # выбрать все симолы, индекс которых кратен 2
['я', 'е', 'л', 'в']

Когда мы ничего не пишем на месте START или STOP, python просто берет минимальное (в случае с START) или максимальное значение (в случае с END).

То есть:

>>> list_of_chars = list('Вячеслав')
>>> print(list_of_chars[:4])
['В', 'я', 'ч', 'е']

Было опущено START и python взял минимальное возможное значение - 0.

Важно, END никогда не входит в результат.

В примере выше мы взяли list_of_chars[:4] и последним символом стала буква е c индексом 3 в исходной строке.

Последний пример в этой секции

Бывает, что нужно взять и развернуть список. Например, когда мы хотим узнать как будет читаться наше имя с другой стороны. С новыми знаниями мы конечно-же сделаем вот так:

>>> name = list('Иван')
>>> reversed_name = name[::-1]
>>> print(reversed_name)
['н', 'а', 'в', 'И']

Работает. Но, не делайте так! Это невозможно читать! В языках программирования много всяких фишек, которые позволяют добиться желаемого совершенно изящными способами. Но порой, эти способы могут ввести в заблуждение и привести к нехорошим ошибкам.

Для машины все равно как вы напишете код. Можно хоть в одну строку (в питоне нельзя), но это потом нельзя будет прочитать и усовершенствовать.

Писать код надо с осознанием, что ты точно будешь его читать в будущем. Даже, если вы не программисты.

Не надо грязи.

Пример выше лучше переписать вот так:

>>> name = list('Иван')
>>> name.reverse()
>>> print(name)
['н', 'а', 'в', 'И']

Здесь используется метод .reverse(), который изменяет начальную строку. Делает то же самое, но читать так лучше.

Вложенные циклы

Выше мы уже определяли матрицу:

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

Теперь давайте её красиво распечатаем, используя вложенные циклы:

>>> for i in range(len(matrix)):
...     for j in range(len(matrix[i])):
...         # end= задаёт какой символ последует за напечатанным текстом, здесь мы 
...         # заменяем символ переноса строки, используемый по-умолчанию, на пробел
...         print(matrix[i][j], end=' ')
... 	print()
...
1 2 3
4 5 6
7 8 9

Про отступы не забываем! Во второй строке 4 пробела, в третьей 8.

На чем можно потренироваться

Можно реализовать консольную программу для игры в крестики-нолики, которая на вход запрашивает координаты крестика или нолика, а на выход выдает изображение игрового поля с отметками.

Домашнее задание

Вам нужно написать программу, которая будет рисовать.

Программа должна спрашивать имя длинной не менее 4 символов.

Домашнее задание поделено на 2 части.

Первая часть

В первой части предлагается заполнить матрицу размером NxN, где N - это длина введенного имени. Заполнить матрицу нужно определенным образом в зависимости от варианта, ниже приведены примеры для имени «иван»

Варианты 1, 7

Справа-налево

н а в и
н а в и
н а в и
н а в и

Варианты 2, 4, 6

Сверху-вниз

и и и и
в в в в
а а а а
н н н н

Варианты 3, 5

снизу-вверх

н н н н
а а а а
в в в в
и и и и

Вторая часть

Следует расплющить матрицу в одномерный список, соединив её строки одну за другой. Например, для варианта 3 должен получится следующий список:

['н', 'н', 'н', 'н', 'а', 'а', 'а', 'а', 'в', 'в', 'в', 'в', 'и', 'и', 'и', 'и']

Программа должна выдавать правильное решение для имени длиной минимум 4 символа

И вывести на экран список элементов в соответствии с номером варианта (нумерация с нуля):

  • 1 вариант: все элементы, начиная с 1 и до конца с шагом 3
  • 2 вариант: с 12 по 3 элементы в обратном порядке
  • 3 вариант: с начала и до 11 элемента
  • 4 вариант: все элементы в обратном порядке
  • 5 вариант: с 11 элемента и до конца
  • 6 вариант: с 2 по 15 элементы, индексы которых в этом списке четные
  • 7 вариант: с 2 по 15 элементы, индексы которых в этом списке нечетные

Выполните задание пройдя по ссылке в GitHub Classroom:


Улучшить эту страницу