Списки

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

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

Например, массив может содержать только целые числа или только вещественные числа или только строки. Список также может содержать элементы только одного типа, что делает его внешне неотличимым от массива. Но вполне допустимо, чтобы в одном списке содержались как числа, так и строки, а также что-нибудь еще.

Создавать списки можно разными способами. Создадим его простым перечисление элементов:

>>> a = [12, 3.85, "black", -4]
>>> a
[12, 3.85, 'black', -4]

Итак, у нас имеется список, присвоенный переменной a. В Python список определяется квадратными скобками. Он содержит четыре элемента. Если где-то в программе нам понадобится весь этот список, мы получим доступ к нему, указав всего лишь одну переменную – a.

Элементы в списке упорядочены, имеет значение в каком порядке они расположены. Каждый элемент имеет свой индекс, или номер. Индексация начинается с нуля. В данном случае число 12 имеет индекс 0, строка "black" – индекс 2. Чтобы извлечь конкретный элемент, надо после имени переменной указать в квадратных скобках индекс необходимого элемента:

>>> a[0]
12
>>> a[3]
-4

В Python существует также индексация с конца. Она начинается с -1:

>>> a[-1]
-4
>>> a[-2]
'black'
>>> a[-3], a[-4]
(3.85, 12)

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

>>> a[0:2]
[12, 3.85]

В данном случае извлекаются первые два элемента с индексами 0 и 1. Элемент с индексом 2 в срез уже не входит. В таком случае возникает вопрос, как извлечь срез, включающий в себя последний элемент? Если какой-либо индекс не указан, то считается, что имеется в виду начало или конец:

>>> a[:3]
[12, 3.85, 'black']
>>> a[2:]
['black', -4]
>>> a[:]
[12, 3.85, 'black', -4]

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

>>> a[1] = 4
>>> a
[12, 4, 'black', -4]

Добавлять и удалять лучше с помощью специальных встроенных методов списка:

>>> a.append('wood')
>>> a
[12, 4, 'black', -4, 'wood']
>>> a.insert(1, 'circle')
>>> a
[12, 'circle', 4, 'black', -4, 'wood']
>>> a.remove(4)
>>> a
[12, 'circle', 'black', -4, 'wood']
>>> a.pop()
'wood'
>>> a
[12, 'circle', 'black', -4]
>>> a.pop(2)
'black'
>>> a
[12, 'circle', -4]

Перечень всех методов списка можно узнать с помощью встроенной в Python функции dir(), передав в качестве аргумента переменную, связанную со списком, или название класса (в данном случае – list). В полученном из dir() списке надо смотреть имена без двойных подчеркиваний.

Для получения информации о конкретном методе следует воспользоваться встроенной функцией help(), передав ей в качестве аргумента имя метода, связанное с объектом или классом. Например, help(a.pop) или help(list.index). Выход из справки – q.

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

>>> b = [1, 2, 3, 4, 5, 6]
>>> b = b[:2] + b[3:]
>>> b
[1, 2, 4, 5, 6]

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

Можно изменить не один элемент, а целый срез:

>>> mylist = ['ab','ra','ka','da','bra']
>>> mylist[0:2] = [10,20]
>>> mylist
[10, 20, 'ka', 'da', 'bra']

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

>>> import random
>>> c = []
>>> i = 0
>>> while i < 10:
...     c.append(random.randint(0,100))
...     i += 1
... 
>>> c
[30, 44, 35, 77, 53, 44, 49, 17, 61, 82]

Практическая работа

  1. Напишите программу, которая запрашивает с ввода восемь чисел, добавляет их в список. На экран выводит их сумму, максимальное и минимальное из них. Для нахождения суммы, максимума и минимума воспользуйтесь встроенными в Python функциями sum(), max() и min().

  2. Напишите программу, которая генерирует сто случайных вещественных чисел и заполняет ими список. Выводит получившийся список на экран по десять элементов в ряд. Далее сортирует список с помощью метода sort() и снова выводит его на экран по десять элементов в строке. Для вывода списка напишите отдельную функцию, в качестве аргумента она должна принимать список.

Примеры решения в android-приложении и pdf-версии курса.

Создано

Обновлено

Комментарии

Более сложная ситуация:

>>> alist = mylist[0:2] + [100,'it is ',200] + mylist[2:] # новый список
>>> a2list = mylist # создается вторая ссылка-переменная на первый список
>>> alist
[10, 20, 100, 'it is ', 200, 'ka', 'da', 'bra'] 
>>> a2list
[10, 20, 'ka', 'da', 'bra']
>>> a2list[0] = '!!!' # изменяем список
>>> a2list
['!!!', 20, 'ka', 'da', 'bra']
>>> mylist # обе переменные связаны с одним списком
['!!!', 20, 'ka', 'da', 'bra']
>>>
_________________________________________________________________________

Проверил - действительно работает. А почему работает, не понимаю!
"#обе переменные связаны с одним списком" - Как? Почему?
Объясните, пожалуйста, в каком месте mylist становится идентичным a2list ?

Ответ на от Гость

mylist - это ссылка на область памяти, где находится список.
Когда выполняется выражение a2list = mylist, то a2list присваивается вовсе не список, а ссылка на область памяти. Получается, что обе переменные ссылаются на одну и туже область, которую могут изменять.

Совсем по иному в Питоне обстоит дело с числами и строками, т.к. они считаются не изменяемыми объектами. Если бы mylist была присвоена строка, то при выполнении выражения a2list = mylist сначала создавалась бы копия значения (строки) в новом месте памяти, а потом ссылка на эту новую область присваивалась бы a2list. В таком случае переменные ссылалась бы на разные объекты.

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

Если требуется получить все-таки копию списка, то можно получить срез со всего списка (взятый срез записывается в отдельную область памяти), а потом присвоить ссылку на этот новый объект переменной:
a2list = mylist[:]

Добрый день.

Объясните пожалуйста, мне не совсем понятны следующие действия:

mylist = [10, 20, 'ka', 'da', 'bra']
alist = mylist[0:2] + [100,'it is ',200] + mylist[2:]
a2list = mylist
a2list[0] = '!!!' 

почему значение первого объекта в mylist и a2list изменяют значение с 10 на !!!, а в alist первое значение всё равно остается 10?

Ответ на от Дмитрий

Списки обладают особенностью. Когда происходит присваивание одного списка другому типа a2list = mylist, то второго списка не создается. Обе ссылки (a2list и mylist) указывают на один и тот же список в памяти.

Если хотят скопировать список, то часто используют срез. Например,

a = [1,2,3]
b = a[0:]

Здесь оба списка содержат числа 1, 2, 3. Но это разные списки. Если бы было a = b, то обе переменные ссылались на один список. И если изменять его через одну, то изменения можно увидеть и через другую.

alist здесь - это уже другой список в памяти. Поэтому когда через a2list меняют первый элемент, то эти изменения видны через mylist, так как эта переменная ссылается на тот же список, что и a2list. alist к этому списку не имеет никакого отношения, т.к. ссылается на другой список.