Уроки Питона №4 / 7. Работа со списками list , list.append(x) в Питоне

Урок 7. Работа со списками (list)

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

 

Что такое список (list) в Python?

Список (list) – это структура данных для хранения объектов различных типов. Если вы использовали другие языки программирования, то вам должно быть знакомо понятие массива. Так вот, список очень похож на массив, только, как было уже сказано выше, в нем можно хранить объекты различных типов. Размер списка не статичен, его можно изменять. Список по своей природе является изменяемым типом данных. Про типы данных можно подробно прочитать здесь. Переменная, определяемая как список, содержит ссылку на структуру в памяти, которая в свою очередь хранит ссылки на какие-либо другие объекты или структуры.

Как списки хранятся в памяти?

Как уже было сказано выше, список является изменяемым типом данных. При его создании в памяти резервируется область, которую можно условно назвать некоторым “контейнером”, в котором хранятся ссылки на другие элементы данных в памяти. В отличии от таких типов данных как число или строка, содержимое “контейнера” списка можно менять. Для того, чтобы лучше визуально представлять себе этот процесс взгляните на картинку ниже. Изначально был создан список содержащий ссылки на объекты 1 и 2, после операции a[1] = 3, вторая ссылка в списке стала указывать на объект 3.

Более подробно эти вопросы обсуждались в уроке 3 (Типы и модель данных).

Создание, изменение, удаление списков и работа с его элементами

Создать список можно одним из следующих способов.

>>> a = [ ]

>>> type(a)

<class 'list'>

>>> b = list()

>>> type(b)

<class 'list'>

Также можно создать список с заранее заданным набором данных.

a = [1, 2, 3]

type(a)

<class 'list'>

Если у вас уже есть список и вы хотите создать его копию, то можно воспользоваться следующим способом:

            0 1   2   3  4       0:4   0 1   2   3  

>>> a = [1, 3,   5,  7]

>>> b = a[:]

>>> print(a)

[1, 3, 5, 7]

>>> print(b)

[1, 3, 5, 7]

или сделать это так:

>>> a = [1, 3, 5, 7]

>>> b = list(a)

>>> print(a)

[1, 3, 5, 7]

>>> print(b)

[1, 3, 5, 7]

В случае, если вы выполните простое присвоение списков друг другу, то переменной b будет присвоена ссылка на тот же элемент данных в памяти, на который ссылается a, а не копия списка а. Т.е. если вы будете изменять список a, то и b тоже будет меняться.

>>> a = [1, 3, 5, 7]

>>> b = a

>>> print(a)

[1, 3, 5, 7]

>>> print(b)

[1, 3, 5, 7]

>>> a[1] = 10

>>> print(a)

[1, 10, 5, 7]

>>> print(b)

[1, 10, 5, 7]

Добавление элемента в список осуществляется с помощью метода append().

>>> a = [ ]      # создаю пустой список

>>> a.append(3)

>>> a.append("hello")

>>> print(a)

[3, 'hello']

Для удаления элемента из списка, в случае, если вы знаете его значение, используйте метод remove(x), при этом будет удалена первая ссылка на данный элемент (но не номер!!!).

>>> b = [2, 3, 5]

>>> print(b)

[2, 3, 5]

>>> b.remove(3)

>>> print(b)

[2, 5]

Если необходимо удалить элемент по его индексу, воспользуйтесь командой del имя_списка[индекс].

>>> c = [3, 5, 1, 9, 6]

>>> print(c)

[3, 5, 1, 9, 6]

>>> del c[2]

>>> print(c)

[3, 5, 9, 6]

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

>>> d = [2, 4, 9]

>>> print(d)

[2, 4, 9]

>>> d[1] = 17

>>> print(d)

[2, 17, 9]

Очистить список можно просто заново его проинициализировав, так как будто вы его вновь создаете. Для получения доступа к элементу списка укажите индекс этого элемента в квадратных скобках.

>>> a = [3, 5, 7, 10, 3, 2, 6, 0]

>>> a[2]

7

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

>>> a[-1]

0

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

>>> a[1:4]   # выводит №1 =5 №2=7 №3=10

[5, 7, 10]

Методы списков

list.append(x)

Добавляет элемент в конец списка. Ту же операцию можно сделать так a[len(a):] = [x].

>>> a = [1, 2]

>>> a.append(3)

>>> print(a)

[1, 2, 3]

list.extend(L)

Расширяет существующий список за счет добавления всех элементов из списка L. Эквивалентно команде a[len(a):] = L.

>>> a = [1, 2]

>>> b = [3, 4]

>>> a.extend(b)

>>> print(a)

[1, 2, 3, 4]

list.insert(i, x)

Вставить элемент x в позицию i.  Первый аргумент – индекс элемента после которого будет вставлен элемент x.

>>> a = [1, 2]

>>> a.insert(0, 5)

>>> print(a)

[5, 1, 2]

>>> a.insert(len(a), 9)

>>> print(a)

[5, 1, 2, 9]

list.remove(x)

Удаляет первое вхождение элемента x из списка.

>>> a = [1, 2, 3]

>>> a.remove(1)

>>> print(a)

[2, 3]

list.pop([i])

Удаляет элемент из позиции i и возвращает его. Если использовать метод без аргумента, то будет удален последний элемент из списка.

>>> a = [1, 2, 3, 4, 5]

>>> print(a.pop(2))

3

>>> print(a.pop())

5

>>> print(a)

[1, 2, 4]

list.clear()

Удаляет все элементы из списка. Эквивалентно del a[:].

>>> a = [1, 2, 3, 4, 5]

>>> print(a)

[1, 2, 3, 4, 5]

>>> a.clear()

>>> print(a)

[]

list.index(x[, start[, end]])

Возвращает индекс элемента.

>>> a = [1, 2, 3, 4, 5]   #     a = [7, 12, 13, 4, 15]

>>> a.index(4)

3 # №3    третий                     #   3

list.count(x)

Возвращает количество вхождений элемента x в список.

>>> a=[1, 2, 2, 3, 3]     #    a=[1, 2, 2, 2,2,2,3, 3]

>>> print(a.count(2))     # a.count(2)

2 # количество вхождений двойки в списке  5

list.sort(key=None, reverse=False)

Сортирует элементы в списке по возрастанию. Для сортировки в обратном порядке используйте флаг reverse=True. Дополнительные возможности открывает параметр key, за более подробной информацией обратитесь к документации.

>>> a = [1, 4, 2, 8, 1]

>>> a.sort()

>>> print(a)

[1, 1, 2, 4, 8]

list.reverse()

Изменяет порядок расположения элементов в списке на обратный.

>>> a = [8,1, 3, 5, 7]

>>> a.reverse()

>>> print(a)

[7, 5, 3, 1,8]

list.copy()

Возвращает копию списка. Эквивалентно a[:].

>>> a = [1, 7, 9]

>>> b = a.copy()  # создаем этим оператором новый список b

>>> print(a)

[1, 7, 9]

>>> print(b)

[1, 7, 9]

>>> b[0] = 8

>>> print(a)

[1, 7, 9]

>>> print(b)

[8, 7, 9]

List Comprehensions

List Comprehensions чаще всего на русский язык переводят как  абстракция списков или списковое включение, является частью синтаксиса языка, которая предоставляет простой способ построения списков. Проще всего работу list comprehensions показать на примере. Допустим вам необходимо создать список целых чисел от 0 до n, где n предварительно задается. Классический способ решения данной задачи выглядел бы так:

n=7  # присваивается n=7

a=[]

for i in range(n):

     a.append(i)

print(a)

 

# [0, 1, 2, 3, 4, 5, 6]

############################

n=10  # присваивается n=7

a=[]

for i in range (2, n+1):

     i=2*i**2

     a.append(i)

print(a)

#[2, 3, 4, 5, 6,7, 8, 9]

Или такая программа с int(input())

 

>>> n = int(input())

7  # присваивается n=7

>>> a=[]

>>> for i in range(0,n+1):

         a.append(i)

>>> print(a)

[0, 1, 2, 3, 4, 5, 6]

И другой пример

 

n = int(input())

#7  # присваивается целый n=7

a=[]

for i in range(n+1):

     a.append(i)

print(a)

#[0, 1, 2, 3, 4, 5, 6, 7]

 

#########

n =8

n = int(n)

a=[ ]

for i in range(n+1):

     a.append(i)

     #print(a)

print(a)

#[0, 1, 2, 3, 4, 5, 6, 7, 8]

 

Использование list comprehensions позволяет сделать это значительно проще:

>>> n = int(input())

7

>>> a = [i for i in range(n)]

>>> print(a)

[0, 1, 2, 3, 4, 5, 6]

или вообще вот так, в случае если вам не нужно больше использовать n:

>>> a = [i for i in range(int(input("введите число:")))]

7

>>> print(a)

[0, 1, 2, 3, 4, 5, 6]

List Comprehensions как обработчик списков

В языке Python есть две очень мощные функции для работы с коллекциями: map и filter. Они позволяют использовать функциональный стиль программирования, не прибегая к помощи циклов, для работы с такими типами как listtuplesetdict и т.п. Списковое включение позволяет обойтись без этих функций. Приведем несколько примеров для того, чтобы понять о чем идет речь.

Пример с заменой функции map.

Пусть у нас есть список и нужно получить на базе него новый, который содержит элементы первого, возведенные в квадрат. Решим эту задачу с использованием циклов:

>>> a = [1, 2, 3, 4, 5, 6, 7]

>>> b = []

>>> for i in a:

           b.append(i**2)

>>> print('a = {}\nb = {}'.format(a, b))

a = [1, 2, 3, 4, 5, 6, 7]

b = [1, 4, 9, 16, 25, 36, 49]

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

>>> a = [1, 2, 3, 4, 5, 6, 7]

>>> b = list(map(lambda x: x**2, a))

>>> print('a = {}\nb = {}'.format(a, b))

a = [1, 2, 3, 4, 5, 6, 7]

b = [1, 4, 9, 16, 25, 36, 49]

В данном случае применена lambda-функция, о том, что это такое и как ее использовать можете прочитать здесь.

Через списковое включение эта задача будет решена так:

>>> a = [1, 2, 3, 4, 5, 6, 7]

>>> b = [i**2 for i in a]

>>> print('a = {}\nb = {}'.format(a, b))

a = [1, 2, 3, 4, 5, 6, 7]

b = [1, 4, 9, 16, 25, 36, 49]

Пример с заменой функции filter.

Построим на базе существующего списка новый, состоящий только из четных чисел:

 a = [1, 2, 3, 4, 5, 6, 7]

 b = []

 for i in a:

         if i%2 == 0:  # остаток от деления на два равен нуля

         b.append(i) # присоединения

print('a = {}\nb = {}'.format(a, b))

print(a)

print(b)

a = [1, 2, 3, 4, 5, 6, 7]

b = [2, 4, 6]

Решим эту задачу с использованием filter:

a = [1, 2, 3, 4, 5, 6, 7]

 b = list(filter(lambda x: x % 2 == 0, a))

 print('a = {}\nb = {}'.format(a, b))

print('a=',a)

print ('a=', b)

вывод:

a = [1, 2, 3, 4, 5, 6, 7]

b = [2, 4, 6]

Решение через списковое включение:

>>> a = [1, 2, 3, 4, 5, 6, 7]

>>> b = [i for i in a if i % 2 == 0]

>>> print('a = {}\nb = {}'.format(a, b))

a = [1, 2, 3, 4, 5, 6, 7]

b = [2, 4, 6]

Слайсы / Срезы

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

>>> a = [i for i in range(10)]

Слайс задается тройкой чисел, разделенных запятой: start:stop:stepStart – позиция с которой нужно начать выборку, stop – конечная позиция, step – шаг. При этом необходимо помнить, что выборка не включает элемент определяемый stop.

Рассмотрим примеры:

>>> # Получить копию списка

>>> a[:]   # start:stop

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

>>> # Получить первые пять элементов списка start:stop

>>> a[0:5]

[0, 1, 2, 3, 4]

>>> # Получить элементы с 3-го по 7-ой

>>> a[2:7]

[2, 3, 4, 5, 6]

>>> # Взять из списка элементы с шагом 2

>>> a[::2]    # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

[0, 2, 4, 6, 8]

>>> # Взять из списка элементы со 2-го по 8-ой с шагом 2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

>>> a[1:8:2]

[1, 3, 5, 7]

Слайсы можно сконструировать заранее, а потом уже использовать по мере необходимости. Это возможно сделать, в виду того, что слайс – это объект класса slice. Ниже приведен пример, демонстрирующий эту функциональность:

>>> s = slice(0, 5, 1)

>>> a[s]

[0, 1, 2, 3, 4]

>>> s = slice(1, 8, 2)

>>> a[s]

[1, 3, 5, 7]

Типо “List Comprehensions”… в генераторном режиме

Есть ещё одни способ создания списков, который похож на списковое включение, но результатом работы является не объект класса list, а генератор. Подробно про генераторы написано в “Уроке 15. Итераторы и генераторы“.

Предварительно импортируем модуль sys, он нам понадобится:

>>> import sys

Создадим список, используя списковое включение :

>>> a = [i for i in range(10)]

проверим тип переменной a:

>>> type(a)

<class 'list'>

и посмотрим сколько она занимает памяти в байтах: (  0,1 )

>>> sys.getsizeof(a)

192

Для создания объекта-генератора, используется синтаксис такой же как и для спискового включения, только вместо квадратных скобок используются круглые:

>>> b = (i for i in range(10))

>>> type(b)

<class 'generator'>

>>> sys.getsizeof(b)

120

Обратите внимание, что тип этого объекта generator, и в памяти он занимает места меньше, чем список, это объясняется тем, что в первом случае в памяти хранится весь набор чисел от 0 до 9, а во втором функция, которая будет нам генерировать числа от 0 до 9. Для наших примеров разница в размере не существенна, рассмотрим вариант с 10000 элементами:

>>> c = [i for i in range(10000)]

>>> sys.getsizeof(c)

87624

>>> d = (i for i in range(10000))

>>> sys.getsizeof(d)

120

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

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

>>> for val in a:

print(val, end=' ')

0 1 2 3 4 5 6 7 8 9

>>> for val in b:

print(val, end=' ')

0 1 2 3 4 5 6 7 8 9

Но с генератором нельзя работать также как и со списком: нельзя обратиться к элементу по индексу и т.п.

Профессиональный репетитор по математике, информатике и физике:

 

Александр Анатольевич Борцов 


КАК ВЫБРАТЬ:
связаться с Александром Анатольевичем
с помощью WhatsApp (лучше) или Telegram
+7-926-859-12-55 

C самого начала своей карьеры, я мечтал собрать в одно целое  мои основные интересы научной деятельности в области Квантовой физики и лазеров: Математику, Информатику, Физику и Обучение, когда еще обучался в аспирантуре.

Успешный математик и физик для школьников и студентов, кандидат физико математических наук, доктор технических наук по специальности радиофизика. Образование: Физический факультет МГУ им.М.В.Ломоносова с отличием, Специальность -Физика. Преподавал в  МЭИ, педагогический стаж более 19 лет. Является автором  монографии на английском языке "Laser Opto-Electronic Oscillator", 2020, изд. Springer. Автор более 60 ти научных публикаций в зарубежных и отечественных научных журналах по темам Квантовая Электроника, Квантовая радиофизика, Лазеры, Наноэлектроника, Лазерный оптоэлектронный генератор и др.. Хорошо   подготовит контрольной работе по математике и физике на 4 курс с помощью интересных методик по расширению памяти. Помощь в оформлении научных статей.

 Обучал основам Python, MathLab, Data Science и Machine Learning. 

Более 320 учащихся  поступили «на бюджет» в университеты и  ВУЗы Москвы: ФИ, МЭИ, и МАИ и т.д.Опыт репетитора по математическому анализу по высшей математике для студентов более 20 лет.Занятия проводятся дистанционно по Skype и Zoom|и очно в Москве м. Китай-город]. Есть большой опыт подготовки к экзаменам по физике и математике по англоязычным программам университетов (SAT,GMAT). По методикам и учебникам университетов готовил к экзаменам по математике и физике  студентов из Канады, Германии, Испании и  Нидерланды. Говорю по английски, владею английским, преподаю на английском математику и физику..
Занятия ведутся Дистанционно по Skype и Zoom и и очно в Москве м. Китай-город

Запись на занятия

Ваше сообщение отправлено