okpython.net
Все для начинающих

Списки в Python

Понятие списка в Python

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

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

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

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

Код Результат pythonCodes
# Получаем пустой список.
li_1 = []
# Выведет [].
print(li_1, end='\n\n')        

# Элементы перечисляем через запятую.
li_2 = [15, "Иван", None, 34.5, True]
# Выведет [15, 'Иван', None, 34.5, True].
print(li_2, end='\n\n') 	

# Последнюю запятую можно не опускать.
li_3 = [1, 2, 3,]
# Выведет [1, 2, 3].
print(li_3, end='\n\n')

# Можно использовать списки списков и т.д.
li_4 = [[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]]
# Выведет [[1, 2, 3], [4, 5, 6], [7, 8, 9]].
print(li_4, end='\n\n') 	

# Эле-ми могут быть любые объекты, любой вложенности.
li_5 = [{'1': 'top', '2': ['abc', [4, 5]]}, 0.3]
# Выведет [{'1': 'top', '2': ['abc', [4, 5]]}, 0.3].
print(li_5)
[]

[15, 'Иван', None, 34.5, True]

[1, 2, 3]

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

[{'1': 'top', '2': ['abc', [4, 5]]}, 0.3]















		
			

Пример №1. Создание списков в Python (часть 1).

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

Создать список можно также при помощи встроенного конструктора типа list(). Если использовать его без аргумента, то он вернет нам пустой список. Если же передать ему итерируемый объект, например, строку или кортеж, то конструктор вернет список, элементами которого будут соответствующие элементы переданного объекта (см. пример №2).

Код Результат pythonCodes
# Получаем пустой список.
li_1 = list()
# Выведет [].
print(li_1, end='\n\n')        

# Получаем список из строки.
li_2 = list('123')
# Выведет ['1', '2', '3'].
print(li_2, end='\n\n')

# Преобразуем кортеж в список.
li_3 = list((15, "Иван", None, 34.5, True))
# Выведет [15, 'Иван', None, 34.5, True].
print(li_3)
[]

['1', '2', '3']

[15, 'Иван', None, 34.5, True]







		
			

Пример №2. Создание списков в Python (часть 2).

Но и это еще не все. В Python для создания списков могут использоваться специальные генераторы списков, которые применяют выражение к каждому элементу передаваемого итерируемого объекта и на основе их вычисления возвращают новый список (см. пример №3).

Код Результат pythonCodes
# Генерируем список из строки.
li_1 = [simb for simb in '123']
# Выведет ['1', '2', '3'].
print(li_1, end='\n\n')

# Используем более сложное выражение.
li_2 = [int(num)*5 for num in '123']
# Выведет [5, 10, 15].
print(li_2)
['1', '2', '3']

[5, 10, 15]




		
			

Пример №3. Создание списков в Python (часть 3).

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

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

Доступ по индексу и срезы списков в Python

Операции доступа по индексу и получения срезов для списков имеют практически тот же самый синтаксис и смысл, что и для строк (см. пример №4).

Код Результат pythonCodes
# Формируем список из целых чисел.
li_1 = [1, 2, 3, 4, 5]

# Получим 1, т.е. 1-й эл-т списка (нумерация начинается с нуля).
print('li_1[0] ->', li_1[0], end='\n\n')	

# Выводим последний эл-т списка (кол-во эл-тов списка минус один).
# Получим 5.
print('li_1[len(li_1)-1] ->', li_1[len(li_1)-1], end='\n\n')

# Можно использовать отрицательные индексы, тогда
# нумерация будет идти с конца и начинаться с -1.
# Опять же получим 5.
print('li_1[-1] ->', li_1[-1])
li_1[0] -> 1

li_1[len(li_1)-1] -> 5

li_1[-1] -> 5







		
			

Пример №4. Доступ к элементам списка по индексу (часть 1).

Однако в отличие от строк списки являются изменяемыми последо­ватель­ностями. Поэтому в результате обращения к элементу списка по его индексу возвращается некоторый объект, расположенный по указанному смещению. А поскольку таким объектом может оказаться не только строка, но и любой другой объект, то для получения доступа к элементам на более глубоком уровне вложенности может потребоваться целая цепочка из нескольких индексов (см. пример №5).

Код Результат pythonCodes
# Простой пример вложенных списков.
li_1 = [3.14, ['abc', [4, 5]], 'кот']

# Выводим число 3.14 (1-й элемент списка).
print('li_1[0] ->', li_1[0], end='\n\n')	

# Выводим 2-й символ строки 'кот'.
print('li_1[2][1] ->', li_1[2][1], end='\n\n')

# Выводим 3-й символ строки 'abc'.
print('li_1[1][0][2] ->', li_1[1][0][2], end='\n\n')	

# Выводим число 5 вложенного списка [4, 5].
print('li_1[1][1][1] ->', li_1[1][1][1])
li_1[0] -> 3.14

li_1[2][1] -> о

li_1[1][0][2] -> c

li_1[1][1][1] -> 5





		
			

Пример №5. Доступ к элементам списка по индексу (часть 2).

Следует добавить, что цепочка доступа к конкретному элементу может иметь и более сложную конструкцию, включающую не только квадратные скобки с индексами для доступа к элементам списков, но и квадратные скобки с ключами для доступа к элементам словарей, и точки для доступа к атрибутам объектов. Например, для списка li = [{'one': 'top', 'two': ['abc', [4, 5]]}, 0.3] цепочка получения доступа ко второму элементу вложенного списка [4, 5] будет иметь вид li[0]['two'][1][1].

Что касается получения срезов для списков, то в результате операции всегда возвращается новый список, состоящий из указанных в срезе элементов исходного списка (см. пример №6). Сам же исходный список не изменяется до тех пор, пока мы не присвоим срезу новое значение (см. примеры №8 и №9).

Код Результат pythonCodes
# Формируем список из целых чисел.
li_1 = [1, 2, 3, 4, 5, 6, 7]

# Получаем список из первых двух эл-тов.
print('li_1[0:2] ->', li_1[0:2], end='\n\n')	
# Можно и так, все равно получим [1, 2].
print('li_1[:2] ->', li_1[:2], end='\n\n')
	
# Получаем список из посл-х двух эл-тов ([6, 7]).
print('li_1[-2:] ->', li_1[-2:], end='\n\n')	

# Получаем список [3, 4, 5] из эл-тов с 3-го по 5-й.
print('li_1[2:5] ->', li_1[2:5], end='\n\n')

# Получим [2, 3, 4, 5] (использ. отриц. индексы).
print('li_1[-6:-2] ->', li_1[-6:-2], end='\n\n')

# Убедимся, что список не изменился.
print('li_1 ->', li_1, end='\n\n')	

# Напоследок выведем копию списка.
print('li_1[:] ->', li_1[:])
li_1[0:2] -> [1, 2]

li_1[:2] -> [1, 2]

li_1[-2:] -> [6, 7]

li_1[2:5] -> [3, 4, 5]

li_1[-6:-2] -> [2, 3, 4, 5]

li_1 -> [1, 2, 3, 4, 5, 6, 7]

li_1[:] -> [1, 2, 3, 4, 5, 6, 7]







		
			

Пример №6. Операция взятия среза у списков.

При извлечении срезов следует помнить, что нумерация элементов в списках начинается с нуля, а элемент с индексом второго предела, указанного в квадратных скобках, не будет присутствовать в срезе. Например, в срезе списка li_1[0:7] будут присутствовать первые семь элементов с индексами от 0 до 6, но не включая элемент с индексом 7.

Как и в случае со строками, один или оба предела среза можно опускать. Если не указывать первый предел, интерпретатор будет начинать срез с первого элемента списка (с индексом 0), а при отсутствии второго предела срез будет идти до конца списка. Если опустить оба предела, мы получим копию списка. Опять же, при необходимости разрешается указывать и третий предел, который будет задавать шаг среза (см. пример №7).

Код Результат pythonCodes
# Формируем список из целых чисел.
li_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Выводим его для наглядности.
print('li_1 ->', li_1, end='\n\n')

# Выводим каждый 2-й элемент среза (слева направо).
# [1, 3, 5, 7].
print('li_1[0:7:2] ->', li_1[0:7:2], end='\n\n')	

# Можно и так, получим опять [1, 3, 5, 7].
print('li_1[:7:2] ->', li_1[:7:2], end='\n\n')
	
# Выводим каждый третий элемент всего списка.
# [1, 4, 7, 10].
print('li_1[::3] ->', li_1[::3], end='\n\n')	

# Выводим каждый 2-й эл-т, считая с конца среза (-1, -2,...).
# Сам срез берется справа налево, если шаг отрицательный.	
# [9, 7, 5].
print('li_1[8:2:-2] ->', li_1[8:2:-2], end='\n\n')

# Выводим каждый 3-й эл-т среза, считая справа налево.
# [8, 5].
print('li_1[-3:1:-3] ->', li_1[-3:1:-3], end='\n\n')

# Выводим каждый 2-й эл-т, считая с конца списка.
# [10, 8, 6, 4, 2].
print('li_1[::-2] ->', li_1[::-2])
li_1 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

li_1[0:7:2] -> [1, 3, 5, 7]

li_1[:7:2] -> [1, 3, 5, 7]

li_1[::3] -> [1, 4, 7, 10]

li_1[8:2:-2] -> [9, 7, 5]

li_1[-3:1:-3] -> [8, 5]

li_1[::-2] -> [10, 8, 6, 4, 2]













		
			

Пример №7. Порядок использования шага среза у списков.

Как видим, шаг среза также может иметь отрицательное значение (аналогично строкам). В этом случае отсчет элементов списка и шагов ведется в противоположном направлении, а границы среза указываются справа налево, т.е. индекс элемента, стоящего правее в списке должен указываться первым. Например, в срезе примера li_1[-3:1:-3] отсчет ведется справа налево, начиная с 3-го элемента, отсчитываемого с конца списка, до элемента с индексом 1, который находится левее и в срез не включается.

Изменяемость списков означает, что мы можем не только получать доступ к элементам списка, но также изменять их значения, вообще удалять или добавлять в список новые элементы. При этом изменению подвергается не копия списка, как в случае со строками, а непосредственно сам список. Так для изменения значения отдельного элемента списка нужно просто найти элемент в списке по индексу и присвоить ему новое значение (см. пример №8).

Код Результат pythonCodes
# Формируем список из 3-х элементов.
li_1 = ['и', ['b', [4, 5]], 0.3]

# Изменяем третий элемент списка (индекс 2).
li_1[2] = 4
# Выведет ['и', ['b', [4, 5]], 4]
print('li_1[2] = 4 ->', li_1, end='\n\n')	

# Изменяем 1-й эл-т вложенного списка [4, 5].
li_1[1][1][0] = 's'
# Выведет ['и', ['b', ['s', 5]], 4].
print("li_1[1][1][0] = 's' -> ", li_1, end='\n\n')		

# Используем отрицательный индекс.
li_1[-3] = [1, 2]
# Выведет [[1, 2], ['b', ['s', 5]], 4].
print('li_1[-3] = [1, 2] ->', li_1, end='\n\n')

# Заменим 1-й элемент пустым списком.
li_1[0] = []
# Выведет [[], ['b', ['s', 5]], 4].
print('li_1[0] = [] ->', li_1)
li_1[2] = 4 -> ['и', ['b', [4, 5]], 4]

li_1[1][1][0] = 's' -> ['и', ['b', ['s', 5]], 4]

li_1[-3] = [1, 2] -> [[1, 2], ['b', ['s', 5]], 4]

li_1[0] = [] -> [[], ['b', ['s', 5]], 4]













		
			

Пример №8. Изменение значений элементов списков.

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

Код Результат pythonCodes
# Формируем список.
li_1 = [1, 2, 3, 4, 5, 6, 7]

# Используем срез из одного элемента.
li_1[0:1] = [4.5]
# Теперь li_1 == [4.5, 2, 3, 4, 5, 6, 7].
print('li_1[0:1] = [4.5] ->', li_1, end='\n\n')

# Заменим два эл-та одним, сократив список.
li_1[0:2] = [0]
# Теперь li_1 == [0, 3, 4, 5, 6, 7].
print('li_1[0:2] = [0] ->', li_1, end='\n\n')

# Заменим один эл-т тремя, расширив список.
li_1[0:1] = [0, 1, 2]
# Теперь li_1 == [0, 1, 2, 3, 4, 5, 6, 7].
print('li_1[0:1] = [1, 2, 3] ->', li_1, end='\n\n')

# Удалим последние два элемента списка.
li_1[-2:] = []
# Теперь li_1 == [0, 1, 2, 3, 4, 5].
print('li_1[-2:] = [] ->', li_1, end='\n\n')

# Заменим срез срезом.
li_1[0:4] = li_1[2:]	
# Теперь li_1 == [2, 3, 4, 5, 4, 5].
print('li_1[0:4] = li_1[2:] ->', li_1, end='\n\n')	

# Используем итерируемый объект.
li_1[0:4] = 'abc'	
# Теперь li_1 == ['a', 'b', 'c', 4, 5].
print('li_1[0:4] = \'abc\' ->', li_1, end='\n\n')	

# Число не является итерируемым объектом.
li_1[0:2] = 5	
# can only assign an iterable (ошибка).
print('li_1[0:2] = 5 ->', li_1)
li_1[0:1] = [4.5] -> [4.5, 2, 3, 4, 5, 6, 7]

li_1[0:2] = [0] -> [0, 3, 4, 5, 6, 7]

li_1[0:1] = [1, 2, 3] -> [0, 1, 2, 3, 4, 5, 6, 7]

li_1[-2:] = [] -> [0, 1, 2, 3, 4, 5]

li_1[0:4] = li_1[2:] -> [2, 3, 4, 5, 4, 5]

li_1[0:4] = 'abc' -> ['a', 'b', 'c', 4, 5]

can only assign an iterable






















		
			

Пример №9. Изменение списков при помощи срезов (часть 1).

Обратите внимание, что для удаления конкретного элемента списка нужно взять срез, включающий только этот элемент, и присвоить ему пустой список. Если же использовать просто индекс, элемент останется, а пустой список станет его значением (см. предыдущий пример №8). Кроме того, при использовании срезов присваиваться должны итерируемые объекты, например, списки, строки или кортежи. В противном случае интерпретатор выдаст ошибку.

При желании в срезах можно использовать и третий параметр, т.е. шаг среза. Но здесь нужно быть осторожным, т.к. количество элементов такого среза должно соответствовать количеству элементов в присваиваемом итерируемом объекте (см. пример №10).

Код Результат pythonCodes
# Формируем список.
li_1 = [1, 2, 3, 4, 5, 6, 7]

# Изменим значение каждого 2-го эл-та списка.
# Cрез включает 4 эл-та: [1, 3, 5, 7].
li_1[0::2] = 'abcd'
# Теперь li_1 ==  ['a', 2, 'b', 4, 'c', 6, 'd'].
print('li_1[0::2] = \'abcd\' ->', li_1, end='\n\n')

# Восстанавливаем список.
li_1 = [1, 2, 3, 4, 5, 6, 7]	

# В срезе 4 эл-та, в строке 6 символов (несоответствие).
li_1[0::2] = 'abcdef'
# attempt to assign sequence of size 6 to extended slice of size 4.
print('li_1[0::2] = \'abcdef\' ->', li_1)
li_1[0::2] = 'abcd' -> ['a', 2, 'b', 4, 'c', 6, 'd']

attempt to assign sequence of size 6 to extended slice of size 4











		
			

Пример №10. Изменение списков при помощи срезов (часть 2).

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

Операторы списков в Python

Поскольку списки относятся к упорядоченным последовательностям, то операторы +, +=, * и *= имеют для них практически тот же смысл, что и для строк (см. пример №11).

Код Результат pythonCodes
# Формируем списки.
li_1 = [1, 2, 3]
li_2 = [4, 5, 6]	

# Осуществляем конкатенацию списков (т.е. объединение).
# Выведет [1, 2, 3, 4, 5, 6].
print('li_1 + li_2 ->', li_1 + li_2, end='\n\n')	
		
# Объединяем с самим собой 3 раза (li_1 + li_1 + li_1).
# Выведет [1, 2, 3, 1, 2, 3, 1, 2, 3].
print('li_1*3 ->', li_1*3, end='\n\n')				

# Тоже, что и li_1 = li_1 + li_2.
li_1 += li_2
# Теперь li_1 == [1, 2, 3, 4, 5, 6].
print('li_1 += li_2 ->', li_1)
li_1 + li_2 -> [1, 2, 3, 4, 5, 6]

li_1*3 -> [1, 2, 3, 1, 2, 3, 1, 2, 3]

li_1 += li_2 -> [1, 2, 3, 4, 5, 6]









		
			

Пример №11. Использование операторов + и * применительно к спискам.

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

Что касается оператора проверки на вхождение in, то примени­тельно к спискам он совершает поиск требуемого объекта (левый операнд) среди элементов целевого списка (правый операнд). В случае успеха операция возвращает True, иначе – False (см. пример №12).

Код Результат pythonCodes
# Формируем список.
li_1 = [1, 2, 3, [4, 5]]
	
# Проверяем наличие числа 8 в списке.
answer = 8 in li_1

# Если операция вернула True,
if answer:
    # выводим подтверждение на экран.
    print('Число 8 присутствует в списке li_1.', end='\n\n')
# Иначе
else:
    # выводим на экран отрицание.
    print('Числа 8 нет в списке li_1.', end='\n\n')	


# Проверим вхождение, используя not in.
if 5 not in li_1[3]:
    # Выводим подтверждение на экран.
    print('Число 5 отсутствует в li_1[3].')				
# Иначе
else:
    # Выводим на экран сообщение.
    print('Число 5 присутствует в li_1[3].')
Числа 8 нет в списке li_1.

Число 5 присутствует в li_1[3].



















		
			

Пример №12. Использование оператора in применительно к спискам.

Напомним, что оператор in может использоваться не только самостоятельно, но и совместно с оператором отрицания not, который инверсирует возвращаемое логическое значение оператора in. Соответственно, например, операция 'крот' not in ['кот', 'кит'] вернет True вместо False.

Если возникает необходимость в обходе элементов списка, то, по аналогии со строками, можно смело использовать оператор цикла for (см. пример №13).

Код Результат pythonCodes
# Формируем список.
li_1 = [1, 2, 3, 4, 5]

# Проверим все ли числа в списке целые.
for elem in li_1:
	
    # Если эл-т не является целым числом,
    if type(elem) is not int:
        # выводим сообщение на экран 
        print('Не все эл-ты списка целые числа.')			
        # и прерываем цикл.
        break

# Eсли цикл завершился успешно,
else:
    # выводим положительный результат. 
    print('Все эл-ты в списке - целые числа.')
Все эл-ты в списке - целые числа.














		
			

Пример №13. Использование цикла for для обхода элементов списка.

Оператор идентичности is возвращает True, если оба операнда указывают на один и тот же объект в памяти компьютера. В противном случае операция возвращает False. Например, инструкция type(0.53) is float вернет True, т.к. вызов функции type(0.53) возвращает не что иное, как сам объект типа float. Добавим, что как и оператор проверки на вхождение in, оператор is может использоваться совместно с оператором отрицания not.

Еще одним полезным и универсальным оператором языка Python является оператор удаления del, который позволяет с легкостью удалять переменные, элементы по индексу или ключу, атрибуты объектов и т.д. Применительно к спискам мы можем использовать del для удаления всего списка, срезов или отдельных его элементов (см. пример №14).

Код Результат pythonCodes
# Формируем список.
li_1 = [1, 2, 3, 4, 5, 6, 7]

# Удаляем первый эл-т списка.
del li_1[0]
# Теперь li_1 == [2, 3, 4, 5, 6, 7].
print('del li_1[0] ->', li_1, end='\n\n')

# Удаляем срез списка.
del li_1[2:4]
# Теперь li_1 == [2, 3, 6, 7].
print('del li_1[2:4] ->', li_1, end='\n\n')	

# Удаляем каждый 2-й эл-т списка.
del li_1[::2]
# Теперь li_1 == [3, 7].
print('del li_1[::2] ->', li_1, end='\n\n')

# Удаляем сам список.
del li_1
# name 'li_1' is not defined.
print(li_1, end='\n\n')
del li_1[0] -> [2, 3, 4, 5, 6, 7]

del li_1[2:4] -> [2, 3, 6, 7]

del li_1[::2] -> [3, 7]

name 'li_1' is not defined













		
			

Пример №14. Использование оператора del применительно к спискам.

На этом рассмотрение базовых операций над списками мы заканчиваем. Осталось рассмотреть методы класса list и встроенные функции, применимые к спискам.

Функции и методы списков в Python

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

  • li.count(x) – возвращает количество в списке li элементов с указанным значением x (см. пример №15). Отметим, что в отличие от аналогичного метода для строк, здесь указывать интервал для поиска нельзя, т.к. метод принимает только один аргумент.
  • li.index(x[, start[, end]]) – возвращает индекс i первого вхождения элемента li[i] со значением x в список li или в срез списка li[start:end], если он задан. В случае неудачного поиска метод вызывает исключение ValueError. Обратите внимание, что при использовании среза отсчет индекса элемента все равно стартует с начала всего списка.
Код Результат pythonCodes
# Создаем список для манипуляций.	
li = ['a', 'b', 'c', 'a', 'b', 'c']

# Ищем кол-во эл-тов со значением 'b'	
n_1 = li.count('b')
# Получим 2.
print('li.count("b") ->', n_1)	
# Ищем кол-во эл-тов со значением 23
n_2 = li.count(23)	
# Получим 0, т.к. эл-тов с таким значением нет в списке.
print('li.count(23) ->', n_2, end='\n\n')	

# Ищем индекс 1-го встретившегося эл-та со значением 'c'.
index_1 = li.index('c')
# Выведет 2.
print('li.index("c") ->', index_1)	
# Тоже самое, но ищем с 4-го элемента списка.
index_2 = li.index('c', 3)
# Получим индекс 5, т.к. ищем не сначала списка.
print('li.index("c", 3) ->', index_2)	
li.count("b") -> 2
li.count(23) -> 0

li.index("c") -> 2
li.index("c", 3) -> 5


	
	
	
	
	
	






			

Пример №15. Методы списков (часть 1).

  • li.insert(i, x) – вставляет элемент со значением x в указанную позицию i. Тот же результат можно получить и при помощи инструкции li[i:i] = [x] (см. пример №16).
  • li.append(x) – добавляет элемент со значением x в конец списка li (тоже самое что и li[len(li):] = [x]).
  • li.extend(iterable) – добавляет элементы из итерируемого объекта iterable в конец списка li (тоже самое что и li[len(li):] = iterable). Не забываем, что итерируемыми являются, например, строки, списки, кортежи, но не числа.
Код Результат pythonCodes
# Создаем список для манипуляций.	
li = ['a', 'b', 'c']
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')
	
# Вставим 'f' перед 'b' (изменяем сам список).
li.insert(1, 'f')
# Выведет ['a', 'f', 'b', 'c']
print('li.insert(1, "f") ->', li)	
# Тоже самое, но через срез.
li[1:1] = ['f']
# Выведет ['a', 'f', 'f', 'b', 'c']
print('li[1:1] = ["f"] ->', li, end='\n\n')		

# Восстанавливаем список.	
li = ['a', 'b', 'c']		
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')			

# Добавляем в конец списка эл-т (другой список).
li.append([7, 8])
# Выведет ['a', 'b', 'c', [7, 8]]
print('li.append([7, 8]) ->', li)			
# Тоже самое, но через срез (здесь вставляем строку).
li[len(li):] = ['ed']		
# Выведет ['a', 'b', 'c', [7, 8], 'ed']		
print('li[len(li):] = ["ed"] ->', li, end='\n\n')			

# Восстанавливаем список.	
li = ['a', 'b']		
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')		

# Добавляем в конец списка эл-ты другого списка.
li.extend([1,2])
# Выведет ['a', 'b', 1, 2]
print('li.extend([1,2]) ->', li)			
# Через срез, но добавим символы строки.
li[len(li):] = 'cd'		
# Выведет ['a', 'b', 1, 2, c, d]		
print('li[len(li):] = "cd" ->', li)			
# А можно  и через плюс (строка - итерируемый объект).
li += 'ef'		
# Выведет ['a', 'b', 1, 2, 3, 4, 'e', 'f']		
print('li += "ef" ->', li)
Стартовый список: ['a', 'b', 'c']

li.insert(1, "f") -> ['a', 'f', 'b', 'c']
li[1:1] = ["f"] -> ['a', 'f', 'f', 'b', 'c']

Стартовый список: ['a', 'b', 'c']

li.append([7, 8]) -> ['a', 'b', 'c', [7, 8]]
li[len(li):] = ["ed"] -> ['a', 'b', 'c', [7, 8], 'ed']

Стартовый список: ['a', 'b']

li.extend([1,2]) -> ['a', 'b', 1, 2]
li[len(li):] = "cd" -> ['a', 'b', 1, 2, 'c', 'd']
li += "ef" -> ['a', 'b', 1, 2, 'c', 'd', 'e', 'f']


	
	















	
	
	
	






			

Пример №16. Методы списков (часть 2).

  • li.remove(x) – удаляет из списка li первый попавшийся элемент, имеющий значение x. Если элемента с указанным значением в списке не окажется, будет вызвано исключение ValueError (см. пример №17).
  • li.pop([i]) – удаляет из списка li элемент с указанным индексом i, а затем возвращает его. Если индекс не указан (параметр необязательный), удаляется последний элемент списка, т.к. по умолчанию i принимается равным -1.
  • li.clear() – удаляет все элементы из списка (тоже самое что и del li[:]).
Код Результат pythonCodes
# Создаем список для манипуляций.	
li = ['a', 'b', 'c']
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')
	
# Удаляем 'b' (изменяем сам список).
li.remove('b')
# Выведет ['a', 'c']
print('li.remove("b") ->', li, end='\n\n')	
		
# Восстанавливаем список.	
li = ['a', 'b', 'c']		
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')			
	
# Удаляем элемент списка с индексом 0.
elem = li.pop(0)
# Выведет a (удаленный эл-т содержит строку)
print('li.pop(0) ->', elem)		
# Выведет ['b', 'c']
print('Теперь li ->', li, end='\n\n')		

# Очищаем список.
li.clear()		
# Выведет []
print('li.clear() ->', li, end='\n\n')	
Стартовый список: ['a', 'b', 'c']

li.remove("b") -> ['a', 'c']

Стартовый список: ['a', 'b', 'c']

li.pop(0) -> a
Теперь li -> ['b', 'c']

li.clear() -> []


	
	
	
	
	
	
	






			

Пример №17. Методы списков (часть 3).

  • li.reverse() – изменяет порядок следования элементов в списке li на обратный. Получить тот же результат можно и с помощью инструкции li = li[::-1] (см. пример №18).
  • li.copy() – возвращает поверхностную копию списка li (li[:]).
Код Результат pythonCodes
# Создаем список для манипуляций.	
li = [1, 2, 3]
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')
    
# Изменяем порядок следования эл-тов на обратный.
li.reverse()
# Выведет [3, 2, 1]
print('li.reverse() ->', li)
# Перевернем список еще раз через срез.
li = li[::-1]
print('li = li[::-1] ->', li, end='\n\n')        
    
# Копируем список (исх. список не изменяется).
copy_li = li.copy()
# Выведет [1, 2, 3]
print('li.copy() ->', copy_li)				
# Тоже самое через срез.
print('li[:] ->', li[:])
Стартовый список: [1, 2, 3]

li.reverse() -> [3, 2, 1]
li = li[::-1] -> [1, 2, 3]

li.copy() -> [1, 2, 3]
li[:] -> [1, 2, 3]











			

Пример №18. Методы списков (часть 4).

  • li.sort(*, key=None, reverse=False) – сортирует элементы списка li. При сортировке используется обычная операция сравнения при помощи оператора <. Соответственно сортировать в одном списке числа и строки без манипуляций не получится. Если же нужно повлиять на алгоритм сортировки элементов списка, следует использовать собственную функцию сравнения, принимающую единственный аргумент и возвращающую значение, которое и будет использовано в операции сравнения. Объект функции нужно передать в качестве значения именованному аргументу key=my_func. Тогда при сортировке для каждого элемента списка будет вызываться переданная функция, а в сравнении будет участвовать не сам элемент, а результат вызова функции (см. пример №19). Кроме того, если использовать именованный аргумент reverse=True, сортировка будет производиться в обратном порядке.
Код Результат pythonCodes
# Создаем список для манипуляций.	
li = ['a', 'bc', 'abc']
# Выведем для наглядности
print('Стартовый список:', li, end='\n\n')
			
# Отсортируем список по умолчанию.
li.sort()
# Выведет ['a', 'abc', 'bc']
print('li.sort() ->', li, end='\n\n')	

# Создаем свою функцию для участия в сравнении.
def my_func(x):
    # Возвращает кол-во эл-тов переданного объекта.
    return len(x)
			
# Сортируем по кол-ву символов в строке.
li.sort(key=my_func)
# Выведет ['a', 'bc', 'abc']
print('li.sort(key=my_func) ->', li, end='\n\n')
			
# Сортируем по убыванию кол-ва символов в строке.
li.sort(key=my_func, reverse=True)
# Выведет ['abc', 'bc', 'a']
print('li.sort(key=my_func, reverse=True) ->', li
Стартовый список: ['a', 'bc', 'abc']

li.sort() -> ['a', 'abc', 'bc']

li.sort(key=my_func) -> ['a', 'bc', 'abc']

li.sort(key=my_func, reverse=True) -> ['abc', 'bc', 'a']


	
	
	
	
	
	
	
	






			

Пример №19. Методы списков (часть 5).

Помимо собственных методов к спискам применим и ряд встроенных функций: min() (возвращает элемент с минимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), max() (возвращает элемент с максимальным значением, при этом элементы должны быть одного типа с возможностью сравнения), sum() (возвращает сумму элементов списка, при этом элементы должны быть числами), len() (возвращает количество элементов в списке), sorted(iterable, *, key=None, reverse=False) (встроенная функция сортировки), filter(function, iterable) (фильтрация элементов списка) и т. д.

Краткие итоги параграфа

  • В Python списки представляют собой упорядоченные изменяемые коллекции объектов произвольного типа с доступом по индексу.
  • Чтобы создать список достаточно перечислить требуемые объекты (элементы списка) через запятую внутри квадратных скобок (например, li = [5.3, 'слон', 2]). Доступ к элементу списка можно получить по его индексу, т.е. порядковому номеру элемента в списке. При этом следует помнить, что индексация элементов в списках начинается с нуля (например, инструкция print(li[0]) выведет первый элемент списка, т.е. число 5.3).
  • Также списки могут быть созданы при помощи конструктора list(iterable) (например, инструкция list('abc') вернет список ['a', 'b', 'c']) и генератора списков (например, [simb for simb in 'abc'] вернет тот же список ['a', 'b', 'c']).
  • Что касается срезов, то для списков они имеют практически тот же смысл, что и для строк. Однако здесь операция среза всегда возвращает новый список, состоящий из указанных в срезе элементов исходного списка. Сам же исходный список не изменяется до тех пор, пока мы не присвоим срезу новое значение.
  • Поскольку списки являются изменяемыми последовательностями, их можно изменять непосредственно: удалять элементы, добавлять новые, изменять значения уже существующих элементов. Например, пусть у нас есть список li = [1, 2, 3]. Тогда инструкция li[0:0] = [4] добавляет в начало списка новый элемент, li[0] = 5 изменяет значение первого элемента списка, а del li[1] удаляет второй элемент списка.
  • Применимы к спискам и знакомые нам арифметические операторы. Так оператор + используется для объединения списков (например, операция конкатенации [1, 2] + [3, 4] вернет список [1, 2, 3, 4]), а комбинированный оператор += расширяет целевой список (левый операнд) за счет элементов присоединяемого в конец дополнительного списка, т.е. правого операнда (например, в результате выполнения инструкций li = [1, 2] и li += [3, 4] в переменной будет храниться список [1, 2, 3, 4]). Что касается оператора умножения * и соответсвующего ему комбинированного оператора *=, то они расширяют список за счет дублирования имеющихся элементов указанное число раз (например, в результате выполнения инструкций li = [1, 2] и li *= 3 в переменной будет храниться список [1, 2, 1, 2, 1, 2]).
  • К спискам применимы оператор in и цикл for. Первый проверяет наличие требуемого объекта среди элементов целевого списка, а второй позволяет поочередно обойти все элементы списка. Кроме того, поскольку списки относятся к изменяемым последовательностям, для них доступен еще и оператор удаления del, который позволяет удалять не только отдельные элементы списка, но также срезы и сам список целиком.
  • В конце мы познакомились с рядом методов типа list. Опять же, они дают нам возможность выполнять широкий спектр операций над списками, а для их использования не нужно импортировать никаких модулей, т.к. они уже встроены в сам интерпретатор. Однако не стоит забывать, что в отличие от строк, списки изменяемы, поэтому их методы в основном изменяют список непосредственно, а не возвращают его измененную копию. Найти методы списков можно в подразделе «Sequence Types – list, tuple, range» раздела «Built-in types» стандартной библиотеки.

Вопросы и задания для самоконтроля

1. Найдите неверное утверждение о списках: являются последовательностями, упорядоченные, неизменяемые. Показать решение.

Ответ. Списки относятся к изменяемым упорядоченным коллекциям объектов. Так что утверждение о том, что списки неизменяемы, ложно.

2. Можно ли поменять местами элементы списка? Удалить или добавить новые? Почему? Показать решение.

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

3. Какие из представленых литералов относятся к типу list: ['зимний', 'летний'], 5.0, '[3, 4]', "Питон, Python"? Проверьте типы программно. Показать решение.

Ответ. Тип list: ['зимний', 'летний'].

Решение Результат pythonCodes
# Выводим типы представленных литералов.
print("Тип ['зимний', 'летний']:", type(['зимний', 'летний']))
print("Тип 5.0:", type(5.0))
print("Тип '[3, 4]':", type('[3, 4]'))
print('Тип "Питон, Python":', type("Питон, Python"))
Тип ['зимний', 'летний']: <class 'list'>
Тип 5.0: <class 'float'>
Тип '[3, 4]': <class 'str'>
Тип "Питон, Python": <class 'str'>
			

4. Исправьте в коде пять ошибок. Показать решение.

Условие pythonCodes
# Сохраним список в переменной.
li = ([1, 2), 3, (4, 5)]		

# Добавляем в список новый эл-т.
li.extend([6, 7])		
# Удаляем из списка 3.
li.remuve('3')
# Очищаем список.
clear(li) 
Условие Решение pythonCodes
# Сохраним список в переменной.
li = ([1, 2), 3, (4, 5)]		

# Добавляем в список новый эл-т.
li.extend([6, 7])		
# Удаляем из списка 3.
li.remuve('3')
# Очищаем список.
clear(li) 
# ([1, 2), 3, (4, 5)].
li = [(1, 2), 3, (4, 5)]		

# li.extend([6, 7])
li.append([6, 7])
# li.remuve('3').
li.remove(3)
# clear(li).
li.clear()

5. Какое значение будет присвоено переменным в инструкциях simb_1 = [1, 2, 3, 4, 5][4] и simb_2 = [1, 2, 3, 4, 5][-4]? Проверьте свой ответ программно. Показать решение.

Условие Решение pythonCodes
# Получаем значения по индексам.
simb_1 = [1, 2, 3, 4, 5][4]  
simb_2 = [1, 2, 3, 4, 5][-4]
# Выведет 5.
print('simb_1:', simb_1)
# Выведет 2.
print('simb_2:', simb_2)
simb_1: 5
simb_2: 2
 
 
 
 
 

6. Какие списки будут присвоены переменным в инструкциях li_1 = [1, 2, 3, 4, 5, 6, 7][1:4], li_2 = [1, 2, 3, 4, 5, 6, 7][-4:-3] и li_3 = [1, 2, 3, 4, 5, 6, 7][::2]? Проверьте свой ответ программно. Показать решение.

Условие Решение pythonCodes
# Получаем срезы.
li_1 = [1, 2, 3, 4, 5, 6, 7][1:4]  
li_2 = [1, 2, 3, 4, 5, 6, 7][-4:-3]
li_3 = [1, 2, 3, 4, 5, 6, 7][::2]

# Выведет [2, 3, 4].
print('li_1:', li_1)
# Выведет [4].
print('li_2:', li_2)         
# Выведет [1, 3, 5, 7].
print('li_3:', li_3)
li_1: [2, 3, 4]
li_2: [4]
li_3: [1, 3, 5, 7]
 



 
 
 
 

7. Как при помощи срезов получить список-«перевертыш», т.е. список, в котором элементы будут идти в обратном порядке? Например, для списка [1, 2, 3, 4, 5] «перевертышем» будет список [5, 4, 3, 2, 1]. Показать решение.

Условие Решение pythonCodes
# Сохраняем список в переменной.
li = [1, 2, 3, 4, 5]
# Получаем список-перевертыш.
li = li[::-1]
# Выводим его на экран.
print(li)
[5, 4, 3, 2, 1]
 

 
 
 

8. В чем заключается главное отличие большинства строковых методов от методов, имеющихся у списков? Показать решение.

Ответ. Большинство методов списков изменяют непосредственно сам список, а строковые методы в основном возвращают измененные копии строки, т.к. сами строки неизменяемы в Python.

9. Как с помощью срезов можно заменить вызовы методов с именами: insert, append, extend, reverse, copy? Показать решение.

Ответ. Можно использовать инструкции li[i:i] = [x], li[len(li):len(li)] = [x], li[len(li):len(li)] = iterable, li = li[::-1], list_copy = li[:] (присваиваем копию переменной, сама инструкция, кстати, не изменяет сам список).

10. В чем заключается главное отличие в использовании методов index(sub[, start[, end]]) и find(sub[, start[, end]]) применительно к спискам и строкам? Показать решение.

Ответ. У списков отсутствует метод find(sub[, start[, end]])!

11. Дополнительные тесты по теме расположены в разделе «Списки» нашего сборника тестов.

12. Дополнительные упражнения и задачи по теме расположены в разделе «Списки» нашего сборника задач и упражнений.

Быстрый переход к другим страницам