Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Python_самоучитель.pdf
Скачиваний:
1296
Добавлен:
29.03.2015
Размер:
835.6 Кб
Скачать

Ревизия: 226

Глава 8. Списки

 

 

 

§8.6. Операции над списками

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

Итак, оператор «+» производит сцепление (конкатенацию) списков:

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

>>>b = [4, 5, 6]

>>>c = a + b

>>>print c

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

Пример, пожалуй, понятен и без пояснений. По аналогии со строками оператор «*» повторит список из первого аргумента указанное количество раз:

>>>[0] * 4 [0, 0, 0, 0]

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

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

Упражнение. Сравните математические свойства операций над списками со свойствами их аналогов для строк (см. упражнение из §2.9).

§8.7. Изменение списков

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

>>>fruit = ["banana", "apple", "quince"]

>>>fruit[0] = "pear"

>>>fruit[-1] = "orange"

>>>print fruit

['pear', 'apple', 'orange']

Оператор построения среза тоже можно использовать аналогичным образом:

>>>a_list = ['a', 'b', 'c', 'd', 'e', 'f']

>>>a_list[1:3] = ['x', 'y']

>>>print a_list

['a', 'x', 'y', 'd', 'e', 'f']

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

>>>a_list = ['a', 'b', 'c', 'd', 'e', 'f']

>>>a_list[1:3] = []

>>>print a_list

85

Ревизия: 226

Глава 8. Списки

 

 

 

['a', 'd', 'e', 'f']

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

>>>a_list = ['a', 'd', 'f']

>>>a_list[1:1] = ['b', 'c']

>>>print a_list

['a', 'b', 'c', 'd', 'f']

>>>a_list[4:4] = ['e']

>>>print a_list

['a', 'b', 'c', 'd', 'e', 'f']

Упражнение. Проверьте, что произойдет, если длина среза будет больше 1, и если второй операнд оператора построения среза будет превосходить длину исходного списка. Можно ли сцепить два списка с помощью оператора построения среза? Если да, то как?

§8.8. Удаление элементов списка

Конечно, удалять элементы из списков с помощью срезов не очень-то удобно, да и ошибиться несложно. Но в Питоне предусмотрен альтернативный вариант, который более читабелен: оператор del. С ним все выглядит гораздо проще:

>>>a = ['one', 'two', 'three']

>>>del a[1]

>>>a

['one', 'three']

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

Кроме того, в качестве параметра оператор может принимать срезы:

>>>a_list = ['a', 'b', 'c', 'd', 'e', 'f']

>>>del a_list[1:5]

>>>print a_list

['a', 'f']

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

§8.9. Объекты и значения

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

>>>a = "banana"

>>>b = "banana"

86

Ревизия: 226

Глава 8. Списки

 

 

 

Мы знаем, что a и b будут указывать на одну и ту же строку "banana", но пока мы не можем сказать, разные ли это строки или это одна и та же строка, на которую указывают две переменные.

Таким образом, пока возможны два варианта:

a

 

“banana”

a

“banana”

 

b

 

 

“banana”

b

 

 

 

 

 

 

В первом случае переменные a и b ссылаются на две разные сущности, содержащие

одинаковые последовательности символов. Во втором – эти переменные ссылаются на одну и ту же строку, т.е. на один и тот же объект.

Пока не будем давать формальное определение понятию объекта – мы вернемся к нему, когда будем изучать объектно-ориентированное программирование в последующих главах.

Каждый объект имеет уникальный идентификатор, который можно получить с помощью функции id(). Так что вызвав эту функцию с параметрами a и b, мы можем определить ссылаются ли они на один и тот же объект или нет.

>>>id(a)

135044008

>>>id(b)

135044008

Вданном случае вы получили один и тот же идентификатор дважды. Это означает, что интерпретатор Питона создал в памяти только один строковый объект, и на него ссылаются обе переменные.

Интересно, что в случае со списками интерпретатор ведет себя по-другому. При присваивании двух списков с одинаковым набором элементов мы получим два разных объекта:

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

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

>>>id(a)

135045528

>>>id(b)

135041704

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

a [1, 2, 3] b [1, 2, 3]

Переменные a и b ссылаются на одинаковые значения, но на разные объекты. Это

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

87

Ревизия: 226

Глава 8. Списки

 

 

 

§8.10. Ссылки на объекты

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

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

>>>b = a

Диаграмма состояния после такого присваивания будет выглядеть так:

a

[1, 2, 3]

b

 

Т.к. две переменные ссылаются на один и тот же список, иногда говорят, что они являются псевдонимами (по-английски, aliases). Таким образом изменение значения первой переменной автоматически затронет значение, на которое ссылается вторая:

>>>b[0] = 5

>>>print a [5, 2, 3]

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

§8.11. Копирование списков

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

Самый простой способ копирования – использовать оператор построения среза:

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

>>>b = a[:]

>>>print b

[1, 2, 3]

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

Теперь мы можем изменять список b, никак не влияя на список a:

>>>b[0] = 5

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

88

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]