2010-11-15 5 views

ответ

9

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

foo = [1,2,3,4,5] 

и вы хотите, вторые, третьи и четвертые элементы, вы можете сделать:

foo[1:4] 

Если опустить один из номеров в срезе, его по умолчанию - начало списка. Так, например

foo[1:] == [2,3,4,5] 
foo[:4] == [1,2,3,4] 

Естественно, если опустить оба номера в срезе вы получите весь список обратно! Однако вы получите копию списка вместо оригинала; на самом деле это стандартная нотация для копирования списка. Обратите внимание на разницу:

>>> a = [1,2,3,4] 
>>> b = a 
>>> b.append(5) 
>>> a 
[1, 2, 3, 4, 5] 
>>> 
>>> a = [1,2,3,4] 
>>> b = a[:] 
>>> b.append(5) 
>>> a 
[1, 2, 3, 4] 

Это происходит потому, что b = a говорит b, чтобы указать на тот же объект, как a, так что добавление к b является такой же, как добавление к a. Копирование списка a позволяет избежать этого. Обратите внимание, что это только работает на одном уровне глубины - если a содержит список, скажем, и вы добавили в этот список в b, вы все равно измените a.

Кстати, есть необязательный третий аргумент для среза, который является параметром - он позволяет вам перемещаться по списку при прыжках больше 1. Таким образом, вы можете написать диапазон (100) [ 0 :: 2] для всех четных чисел до 100.

+1

или вы можете написать диапазон (0, 100, 2) –

+0

также может использоваться для назначения срезу, например 'a [2: 4] = [4,5,6,7,8]' –

5

Если self.var является mutable sequence, он вернет shallow copy этой последовательности.

Если self.var непреложный built-in sequence, такие как string или tuple, большинство реализаций будет возвращать self.var себя.

+0

-1 Если var относится к ** изменяемой ** последовательности, он вернет ** ссылку на ** мелкую копию этой последовательности. Если var ссылается на неизменяемую последовательность (например, str, unicode, кортеж), она должна (для эффективности) возвращать исходную ссылку. –

+0

@John, первая часть вашего комментария технически правильная, но я не уверен во второй части (см. Последнюю ссылку в моем ответе). Кроме того, я думаю, что вопросник больше интересуется тем, что код действительно * делает *, а не тем, что он должен делать * –

+0

Усиление «должно»: второй случай с CPython вернет исходную ссылку для встроенных объектов (поскольку исполнители не глупы). Нет такой гарантии для пользовательских объектов. «Общий фрагмент» (ваша последняя ссылка) не имеет отношения к случаю '[:]', который уже «разделяется» не-глупыми реализациями. –

2

Это создаст мелкую копию списка и вернет его.

«Мелкая копия», в отличие от «глубокой копии», означает, что список будет создавать только новые копии ссылок в нем, а не фактические объекты. То есть будет создан новый список с теми же ссылками на объекты, но сами объекты останутся прежними.

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

+0

Кто сказал, что это список? Это может быть любой объект, который поддерживает операцию разрезания, например. объект xlm.etree.ElementTree.Element –

+0

Конечно, вы правы. Я мог бы сказать «любой объект, который реализует функциональность срезания», но я думаю, что это вряд ли помогло - не в этом вопросе, насколько я понимаю, я думаю, что важная часть проблемы с мелкой и глубокой копией. – slezica

2

Это называется список нарезка:

[от: до: пропустить]

[от: до]

Так что, если я говорю:

list = range(20) 
print list[1:3] #returns [2, 3] 
print list[1:12:3] #returns [2, 5, 8, 11] 
print list[14:] #because theres no end: [15, 16, 17, 18, 19] 
print list[14:-2] #-2 from the end: [15, 16, 17] 
+0

Это называется срез, операция, предоставляемая несколькими различными типами объектов. –

1

вы можете использовать операторы со списком следующих способов:

список = [1,2,3,4,5,6,7,8,9]

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

list [0: 3] показывает [1,2,3], вызывают его начинается с положения первого номера и заканчивается в позиции, предшествующей второму номеру

список [: 3] показывает то же, что и раньше, первое число отсутствует, поэтому нет начального предела

list [5:] показывает список с пятой позиции до конца [6,7,8,9]

Теперь, если x или y из списка [x, y] отрицательный, тогда он начинается, если x из положения x, и если он заканчивается от len (list) -2 position Например: list [- 1: 3] = [2,3]

Теперь вы можете иметь 2: например [x: y: z] здесь x указывает начальную ячейку, y последнюю ячейку (которая не включена в возвращаемый диапазон) и z шаг, на котором последовательность продвигается list [0: 5: 2] = [0,2,4]

Смежные вопросы