Шаг 62.
Основы языка Python.
Списки, кортежи, множества и диапазоны. Создание списка

    На этом шаге мы рассмотрим способы создания списка.

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

    В некоторых языках программирования (например, в РНР) можно добавить элемент, указав пустые квадратные скобки или индекс больше последнего индекса. В языке Python все эти способы приведут к ошибке:

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

>>> х = у = [1,   2] # Якобы создали два объекта
>>> х,   у
([1, 2], [1, 2])

    В этом примере мы создали список из двух элементов и присвоили значение переменным х и у. Теперь попробуем изменить значение в переменной у:

>>> у[1]  = 100 # Изменяем второй элемент
>>> х, у # Изменилось значение сразу в двух переменных
([1, 100], [1, 100])

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

>>> х, y = [1, 2], [1, 2]
>>> у[1] = 100 # Изменяем второй элемент
>>> х, у
([1, 2], [1, 100])

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

>>> arr =[ [] ] * 2 # Якобы создали два вложенных списа
>>> arr
[[], []]
>>> arr[0].append (5) # Добавляем элемент
>>> arr # Изменились два элемента
[[5], [5]]

    Создавать вложенные списки следует с помощью метода append () внутри цикла:

>>> arr = [ ]
>>> for i in range (2): arr.append ([])

>>> arr 
[ [], [] ]
>>> arr [0].append(5); arr
[ [5], [] ]

    Можно также воспользоваться генераторами списков:

>>> arr = [ []   for  i  in range (2) ]
>>> arr
[ [], [] ]
>>> arr[0] .append(5);   arr
[ [5], [] ]

    Проверить, ссылаются ли две переменные на один и тот же объект, позволяет оператор is. Если переменные ссылаются на один и тот же объект, то оператор is возвращает значение True:

>>> х = у = [1, 2]   # Неправильно
>>> х is у # Переменные содержат ссыпку на один и тот же список
True
>>> х, у = [1, 2], [1, 2] # Правильно
>>> х is у	 # Это разные объекты
False

    Но что же делать, если необходимо создать копию списка? Первый способ заключается в применении операции извлечения среза, второй - в использовании функции list (), а третий - в применении появившегося в Python 3.3 метода сору ().

    На первый взгляд может показаться, что мы получили копию - оператор is показывает, что это разные объекты, а изменение элемента затронуло лишь значение переменной у. В данном случае вроде все нормально. Но проблема заключается в том, что списки в языке Python могут иметь неограниченную степень вложенности. Рассмотрим это на примере:

    В этом примере мы создали список, в котором второй элемент является вложенным списком. Далее с помощью функции list () попытались создать копию списка. Как и в предыдущем примере, оператор is показывает, что это разные объекты, но посмотрите на результат. Изменение переменной у затронуло и значение переменной х. Таким образом, функция list () и операция извлечения среза создают лишь поверхностную копию списка.

    Чтобы получить полную копию списка, следует воспользоваться функцией deepcopy() из модуля сору:

    Функция deepcopy () создает копию каждого объекта, при этом сохраняя внутреннюю структуру списка. Иными словами, если в списке существуют два элемента, ссылающиеся на один объект, то будет создана копия объекта, и элементы будут ссылаться на этот новый объект, а не на разные объекты. Пример:

    На следующем шаге мы рассмотрим операции над списками.




Предыдущий шаг Содержание Следующий шаг