Мне нужно хорошее объяснение (ссылки будут плюсом) по нотации Python's slice.
На мой взгляд, эту нотацию нужно немного подтянуть.
Она выглядит чрезвычайно мощной, но я еще не разобрался в ней.
Все очень просто:
a[start:stop] # items start through stop-1
a[start:] # items start through the rest of the array
a[:stop] # items from the beginning through stop-1
a[:] # a copy of the whole array
Существует также значение step
, которое может быть использовано с любым из вышеперечисленных:
a[start:stop:step] # start through not past stop, by step
Главное помнить, что значение :stop
представляет собой первое значение, которое не находится в выбранном фрагменте. Таким образом, разница между stop
и start
заключается в количестве выбранных элементов (если step
равен 1, по умолчанию).
Другой особенностью является то, что start
или stop
может быть отрицательным числом, что означает, что отсчет ведется от конца массива, а не от начала. Таким образом:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
Аналогично, step
может быть отрицательным числом:
a[::-1] # all items in the array, reversed
a[1::-1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::-1] # everything except the last two items, reversed
Python добр к программисту, если элементов меньше, чем вы просите. Например, если вы просите a[:-2]
, а a
содержит только один элемент, то вместо ошибки вы получите пустой список. Иногда вы предпочтете ошибку, поэтому вы должны знать, что такое может случиться.
slice()
Оператор нарезки []
фактически используется в приведенном выше коде с объектом slice()
, используя нотацию :
(которая действительна только в пределах []
), то есть:
a[start:stop:step]
эквивалентно:
a[slice(start, stop, step)]
Объекты Slice также ведут себя немного по-разному в зависимости от количества аргументов, аналогично range()
, т.е. поддерживаются как slice(stop)
, так и slice(start, stop[, step])
.
Чтобы не указывать конкретный аргумент, можно использовать None
, так что, например, a[start:]
эквивалентно a[slice(start, None)]
или a[::-1]
эквивалентно a[slice(None, None, -1)]
.
Хотя нотация на основе :
очень полезна для простых нарезок, явное использование объектов slice()
упрощает программную генерацию нарезок.
В учебнике по Python об этом говорится (прокрутите страницу вниз, пока не дойдете до части о нарезке).
Диаграмма в формате ASCII также полезна для запоминания того, как работают срезы:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
Один из способов запомнить, как работают срезы, - это представить индексы как указатели между символами, причем левый край первого символа имеет номер 0. Тогда правый край последнего символа строки из n символов имеет индекс n.
Перечисление возможностей, допускаемых грамматикой:
>>> seq[:] # [seq[0], seq[1], ..., seq[-1] ]
>>> seq[low:] # [seq[low], seq[low+1], ..., seq[-1] ]
>>> seq[:high] # [seq[0], seq[1], ..., seq[high-1]]
>>> seq[low:high] # [seq[low], seq[low+1], ..., seq[high-1]]
>>> seq[::stride] # [seq[0], seq[stride], ..., seq[-1] ]
>>> seq[low::stride] # [seq[low], seq[low+stride], ..., seq[-1] ]
>>> seq[:high:stride] # [seq[0], seq[stride], ..., seq[high-1]]
>>> seq[low:high:stride] # [seq[low], seq[low+stride], ..., seq[high-1]]
Конечно, если (highlow)%stride != 0
, то конечная точка будет немного ниже, чем high-1
.
Если stride
отрицателен, то упорядочивание немного меняется, так как мы ведем обратный отсчет:
>>> seq[::-stride] # [seq[-1], seq[-1-stride], ..., seq[0] ]
>>> seq[high::-stride] # [seq[high], seq[high-stride], ..., seq[0] ]
>>> seq[:low:-stride] # [seq[-1], seq[-1-stride], ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]
Расширенные нарезки (с запятыми и многоточиями) в основном используются только специальными структурами данных (например, NumPy); базовые последовательности их не поддерживают.
>>> class slicee:
... def __getitem__(self, item):
... return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
Ответы выше не't обсуждают назначение кусочек. Чтобы понять назначение ломтик, он'ы полезно добавить еще одно понятие в ASCII искусства:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
Slice position: 0 1 2 3 4 5 6
Index position: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
'P'
>>> p[5]
'n'
# Slicing gives lists
>>> p[0:1]
['P']
>>> p[0:2]
['P','y']
Одна эвристика является, на срез от нуля до n, думаю: "в ноль-это начало, начать с начала и взять n элементов в списке и".
>>> p[5] # the last of six items, indexed from zero
'n'
>>> p[0:5] # does NOT include the last item!
['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
['P','y','t','h','o','n']
Другой эвристики, то "для любой срез, замените начать с нуля, применить предыдущий алгоритм вам конец списка, то рассчитывать на первое число обратно до ЧОП элементов от начала и"
>>> p[0:4] # Start at the beginning and count out 4 items
['P','y','t','h']
>>> p[1:4] # Take one item off the front
['y','t','h']
>>> p[2:4] # Take two items off the front
['t','h']
# etc.
Первое правило назначения срез, что после нарезки возвращает список, назначение срез требует список (или другой метод):
>>> p[2:3]
['t']
>>> p[2:3] = ['T']
>>> p
['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
Второе правило назначения ломтик, который вы можете видеть выше, что часть списка возвращается индексации срез, что'с той же части, которая изменяется по заданию кусочек:
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
Третье правило ломтик задание, список (повторяемое) не'т должны иметь одинаковую длину; индексированный кусочек просто вырезаны и заменены в массовом порядке независимо от назначения:
>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
['P','y','s','p','a','m','o','n']
Самая сложная часть, чтобы привыкнуть к это задание с пустыми кружочками. Используя эвристика 1 и 2 это's легкий для того чтобы получить вашу голову вокруг индексация пустой кусочек:
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
И затем однажды вы'вэ видел, что назначение кусочек на пустой кусочек тоже есть смысл:
>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
['P','y','t','h','x','y','o','n'] # The result is longer still
Обратите внимание, что, поскольку мы не меняем второе число среза (4), вставленных элементов всегда укладывают прямо против 'О', даже когда мы'вновь назначив на пустой кусочек. Поэтому положение пустого назначения фрагмент является логическим продолжением позиции, для непустых задания среза.
Резервное копирование немного, что происходит, когда вы продолжаете идти с нашей процессией подсчитывая кусочек начала?
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
С нарезки, как только вы'повторно сделано, вы'вновь сделал; это не'т начать отрезая назад. В Python вы не'т получить отрицательный успехов, если явно задать для них с помощью отрицательных чисел.
>>> p[5:3:-1]
['n','o']
Там какие-то странные последствия в "как вы'повторно сделано, вы'вновь сделал" по правилу:
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
>>> p[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
В самом деле, по сравнению с индексацией, питона, нарезка странная ошибка-доказательство:
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Это может пригодиться иногда, но это также может привести к несколько странным поведением:
>>> p
['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']
В зависимости от вашего приложения, что может... или не может... быть то, что вы надеялись там!
<ч/>
Ниже приводится текст моего первоначального ответа. Это было полезно для многих людей, поэтому я не'т хотите, чтобы удалить его.
>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]
Это может также уточнить различие между нарезанием и индексации.
объяснить на языке Python'ы срез нотации
Короче, двоеточие (
:
) в подстрочное обозначение (subscriptable[subscriptarg]
) делает диапазонное представление - который имеет дополнительные аргументы,пуск
,стоп
,шаг
:
sliceable[start:stop:step]
Питон нарезки является вычислительно быстрый способ методически части доступа вашим данным. На мой взгляд, быть даже промежуточная программист Python, это's один из аспектов языка, которые надо знать.
Для начала, позвольте'ы определить несколько терминов:
старт: начальный индекс среза, он будет включать в себя элемент по этому индексу, если он такой же, как и стоп, по умолчанию 0, т. е. первый индекс. Если это's отрицательный, это означает, чтобы начать
Н
элемента из конца. остановка индекс конца среза, это не включать элемент по этому индексу, значение по умолчанию-длина последовательности, нарезанный, то есть вплоть до конца. шаг: сумма, на которую увеличивается индекс, по умолчанию 1. Если это's отрицательный, вы'вэ нарезки на обходе в обратном порядке.Как Работает Индексация
Вы можете сделать любой из этих положительных или отрицательных чисел. Значение положительных чисел очень проста, но для отрицательных чисел, так как индексы в Python, вы считать в обратном порядке от конца для начала и стоп, а для шаг, вы просто уменьшить свой индекс. Этот пример из документации'ы учебник]1, но я'вэ изменил его немного, чтобы указать, какой элемент в последовательности каждого индекса ссылок:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Использовать срез нотации с последовательностью, которая поддерживает его, вы должны содержать по крайней мере одну двоеточия в квадратных скобках, которые следуют за последовательностью (которая на самом деле реализации `метод getitem метод последовательности, согласно модели данных на Python.) Диапазонное представление как это работает:
sequence[start:stop:step]
И напомнить, что существуют значения по умолчанию для начала, стоп и шаг, чтобы получить доступ к опции по умолчанию, просто оставлю аргумент. Диапазонное представление, чтобы получить последние девять элементов из списка (или любую другую последовательность, которая его поддерживает, как струна) будет выглядеть так:
my_list[-9:]
Когда я вижу это, я читал часть в скобках как "9-й от конца, до конца.&и" (на самом деле, я сокращу его мысленно как "-9, дальше")
Полную запись
my_list[-9:None:None]
и подставлять значения по умолчанию (на самом деле, когда " шаг "отрицательно," стоп " 'ы по умолчанию -лен(списка my_list) - 1
, значит нет
для остановки на самом деле просто означает, что он идет в зависимости от конца шаге его):
my_list[-9:len(my_list):1]
В двоеточие, :
, это то, что говорит на языке Python вы'вновь давая ему кусочек, а не обычный показатель. Что's, почему идиоматические способ сделать мелкую копию списков в Python 2 есть
list_copy = sequence[:]
И очищая их с:
del my_list[:]
(В Python 3 получает список.копияи
список.ясный метод.)
шаг
является отрицательной, по умолчанию для пуск
и стоп
изменитьПо умолчанию, когда " шаг "аргумент пуст (или "нет"), оно присваивается +1
.
Но вы можете пройти в отрицательное целое число, а список (или большинство других стандартных slicables) будет отрезана от конца к началу.
Таким образом, негативный срез будет изменять значения по умолчанию для пуск
и стоп
!
Мне нравится поощрять пользователей, чтобы прочитать источник, а также документацию. В исходный код объектов-фрагментов и эта логика нашла здесь. Сначала мы определяем, если шаг отрицателен:
step_is_negative = step_sign < 0; Если это так, то нижняя граница равна
-1
то мы режем все, вплоть до и включая начало, а верхняя-длина минус 1, Что означает, что мы начнем с конца. (Заметим, что семантика этого-1
- это разные с-1
, что пользователи могут передавать указатели в Python с указанием последнего пункта.) если (step_is_negative) { низкий = PyLong_FromLong(-1л); если (меньше == нуль) goto ошибки;верхний = PyNumber_Add(длина, ниже); если (верхние == нуль) goto ошибки; } В противном случае " шаг " является положительным, а нижняя граница будет равна нулю, а верхняя граница (которой мы идем вплоть до, но не включая) Длина нарезанной список. еще { низкий = _PyLong_Zero; Py_INCREF(нижняя); верх = длина; Py_INCREF(верхний); } Тогда, возможно, нам придется применить стандартные на "пуск" и "стоп" - по умолчанию, затем "пуск", определяется как верхняя граница, когда " шаг " является отрицательным: если (само-и GT;старт == Py_None) { начать = step_is_negative ? верхняя : нижняя; Py_INCREF(старт); } и "стоп", нижняя граница: если (само-и GT;стоп == Py_None) { стоп = step_is_negative ? нижняя : верхняя; Py_INCREF(стоп); }
Дать срезам описательное имя!
Вы можете найти его полезным, чтобы отделить формирования среза от прохождения его в список.метод getitem метод (что'ы что в квадратных скобках У). Даже если вы'повторно не новый, он держит ваш код более читабельным, так что другие, которые, возможно, придется читать ваш код будет легче понять, что вы'повторно делать. Однако, вы можете'Т просто присвоить несколько чисел, разделенных двоеточиями переменной. Вы должны использовать объект-фрагмент:
last_nine_slice = slice(-9, None)
Второй аргумент, "нет", не требуется, так что первый аргумент интерпретируется как "запустить" аргумент в противном случае это будет "стоп" Аргумент. Затем вы можете передать объект фрагмента последовательности:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Это'интересно, что диапазоны также взять ломтики:
>>> range(100)[last_nine_slice]
range(91, 100)
Так как срезы списков в Python создавать новые объекты в памяти, еще одна важная функция, чтобы быть в курсе о модуле itertools.делает islice. Как правило, вы'll хочу перебрать кусочек, а не просто он создан статически в памяти.
делает islice` идеально подходит для этого. Один нюанс, он не'т поддерживать отрицательных аргументов "пуск", "стоп", или "шаг", так что, если это's не проблема, вам может понадобиться для расчета индексов или обратный метод заранее.
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
а теперь:
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Тот факт, что срезы список сделать копию-это функция самих списков. Если вы'вновь нарезая сложные объекты, как панды фрейма данных, он может вернуть взгляд на оригинал, а не копия.
И пару вещей, которые были'т очевидным для меня, когда я впервые увидел синтаксис:
>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]
Легкий путь в обратной последовательности!
И если ты хотел, почему-то, каждый второй товар в обратной последовательности:
>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]
В Python 2.7
Нарезки на Python
[a:b:c]
len = length of string, tuple or list
c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward.
a -- When c is positive or blank, default is 0. When c is negative, default is -1.
b -- When c is positive or blank, default is len. When c is negative, default is -(len+1).
Понимание назначения индексов является очень важным.
In forward direction, starts at 0 and ends at len-1
In backward direction, starts at -1 and ends at -len
Когда вы говорите [А:В:С], вы говорите, в зависимости от знака с (вперед или назад), запустите при и заканчивается на " Б " (кроме элемента с индексом ВТН). Использовать приведенные выше правила индексации и помните вы найдете только элементы в этом диапазоне:
-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1
Но этот ряд продолжается в обоих направлениях бесконечно:
...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....
Например:
0 1 2 3 4 5 6 7 8 9 10 11
a s t r i n g
-9 -8 -7 -6 -5 -4 -3 -2 -1
Если ваш выбор А, B и C позволяет перекрывать диапазон выше, как вы пройти через правила А,B,C выше вы получите либо список с элементами (задели во время обхода) или вы получите пустой список.
Одна последняя вещь: если A и B равны, то также вы получаете пустой список:
>>> l1
[2, 3, 4]
>>> l1[:]
[2, 3, 4]
>>> l1[::-1] # a default is -1 , b default is -(len+1)
[4, 3, 2]
>>> l1[:-4:-1] # a default is -1
[4, 3, 2]
>>> l1[:-3:-1] # a default is -1
[4, 3]
>>> l1[::] # c default is +1, so a default is 0, b default is len
[2, 3, 4]
>>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1)
[4, 3, 2]
>>> l1[-100:-200:-1] # Interesting
[]
>>> l1[-1:-200:-1] # Interesting
[4, 3, 2]
>>> l1[-1:-1:1]
[]
>>> l1[-1:5:1] # Interesting
[4]
>>> l1[1:-7:1]
[]
>>> l1[1:-7:-1] # Interesting
[3, 2]
>>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction
[4]
Нашли хороший столик в http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
в <предварительно><код>индексы Python и срезы на шесть-элемент списка. Индексы перечисляет элементы, кусочки перечисляет пробелы между элементами.
Индекс сзади: -6 -5 -4 -3 -2 -1 а=[0,1,2,3,4,5] а[1:]==[1,2,3,4,5] Индекс спереди: 0 1 2 3 4 5 лен(а)==6 а[:5]==[0,1,2,3,4] +---+---+---+---+---+---+ а[0]==0 в[:-2]==[0,1,2,3] | А | B | С | D | Е | F | а[5]==5 а[1:2]==[1] +---+---+---+---+---+---+ а[-1]==5 а[1:-1]==[1,2,3,4] Срез спереди: : 1 2 3 4 5 : а[-2]==4 Кусочек от задней: : -5 -4 -3 -2 -1 : Б=а[:] б==[0,1,2,3,4,5] (неполную копию)</код></пре>
После ее использования немного я понимаю, что самое простое описание, что это точно так же как доводы " за " петля...
(from:to:step)
Любой из них являются обязательными:
(:to:step)
(from::step)
(from:to)
Тогда отрицательная индексация просто нуждается в вас, чтобы добавить длину строки до отрицательных показателей, чтобы понять это.
Это в любом случае работает на меня...
Мне легче запомнить, как это работает, и тогда я смогу выяснить, какие конкретные старт/стоп/шаг комбинацию.
Это'ы поучительна для понимания диапазона()` сначала:
def range(start=0, stop, step=1): # Illegal syntax, but that's the effect
i = start
while (i < stop if step > 0 else i > stop):
yield i
i += step
Начнем с "начала", приращение, "шаг", не доходят до "стоп". Очень просто.
Важно помнить о негативных шаг заключается в том, что "стоп" всегда в основе конца, будь это's выше или ниже. Если вы хотите нарезать в обратном порядке, это'ы намного чище делать разворот отдельно: например, 'причина'[1:-2][::-1]
отрезает один символ слева, две справа, затем инвертирует. (См. также обратная()
.)
Нарезки последовательности такой же, за исключением того первого нормализует отрицательными индексами, и он никогда не может выходить за пределы последовательности:
Тодо: код ниже был баг с "никогда не выходить за пределы последовательности" когда АБС(шаг)>1; я думаю я исправил это, чтобы быть правильным, но это'ы трудно понять.
def this_is_how_slicing_works(seq, start=None, stop=None, step=1):
if start is None:
start = (0 if step > 0 else len(seq)-1)
elif start < 0:
start += len(seq)
if not 0 <= start < len(seq): # clip if still outside bounds
start = (0 if step > 0 else len(seq)-1)
if stop is None:
stop = (len(seq) if step > 0 else -1) # really -1, not last element
elif stop < 0:
stop += len(seq)
for i in range(start, stop, step):
if 0 <= i < len(seq):
yield seq[i]
Дон'т беспокоиться о детали нет - просто помните, что опуская "пуск" и стоп/или всегда делает правильные вещи, чтобы дать вам всю последовательность.
Нормализация отрицательные индексы первого запуска и/или остановки следует отсчитывать с конца самостоятельно: 'причина'[1:-2] == 'аbcde'[1:3] == 'до н. э.'
несмотря на спектр(1,-2) == []
.
Нормализация иногда воспринимается как "по модулю длины", но обратите внимание, он добавляет длину только один раз: например, 'причина'[-53:42]
просто всю строку.
Index:
------------>
0 1 2 3 4
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
0 -4 -3 -2 -1
<------------
Slice:
<---------------|
|--------------->
: 1 2 3 4 :
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
: -4 -3 -2 -1 :
|--------------->
<---------------|
Я надеюсь, что это поможет вам модель в список в Python.
Ссылка: http://wiki.python.org/moin/MovingToPythonFromOtherLanguages
Я использую "в качестве индексных пункта между элементами" и способ мышления об этом сам, но можно и так сказать, который иногда помогает другим сделать это:
mylist[X:Y]
X-это индекс первого элемента, который вы хотите. Y-это индекс первого элемента Дон'т хотите.
Нотации Python для нарезки:
a[start:end:step]
начала
и конца
, отрицательные значения интерпретируются как относительно конца последовательности.[+0:-0:1]
.начала
и конца
Обозначение охватывает (включает) матриц и многомерных массивов. Например, чтобы нарезать всю столбцов вы можете использовать:
m[::,0:2:] ## slice the first two columns
Слайсы содержат ссылки, а не копии, элементов массива. Если вы хотите сделать копию массива, вы можете использовать deepcopy()
.
Это, как я учу ломтики для новичков:
Понимание разницы между индексацией и нарезки:
Вики Python имеет эту удивительную картину, которая четко отличает индексации и разделения.
Это список с шестью элементами в нем. Чтобы понять, отрезая лучше, считайте, что список как набор из шести ящиков, помещенных вместе. Каждая коробка имеет алфавит в его.
Индексация как общаться с содержимым коробки. Вы можете проверить содержимое любого окна. Но вы можете'т проверить содержимое нескольких коробок одновременно. Вы даже можете заменить содержимое коробки. Но вы можете't поставьте два шара в одной коробке или заменить двумя мячами одновременно.
In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']
In [124]: alpha[0]
Out[124]: 'a'
In [127]: alpha[0] = 'A'
In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']
In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]
TypeError: list indices must be integers, not tuple
Нарезки как общаться с собой коробки. Вы можете забрать первую коробку и поместите его на другой стол. Забрать коробку, все, что вам нужно знать, это позиция начало и конец коробке.
Вы даже можете подобрать первые три коробки и две последние коробки или все коробки между 1 и 4. Так, вы можете выбрать любой набор из коробки, Если вы знаете начало и конец. Эти позиции называются запуска и остановки позиции.
Интересно то, что вы можете заменить несколько коробок сразу. Также вы можете разместить несколько ящиков, куда вам нравится.
In [130]: alpha[0:1]
Out[130]: ['A']
In [131]: alpha[0:1] = 'a'
In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']
In [133]: alpha[0:2] = ['A', 'B']
In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']
In [135]: alpha[2:2] = ['x', 'xx']
In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']
Нарезки С Шагом:
До сих пор вы подобрали постоянно коробки. Но иногда нужно подбирать по отдельности. Например, вы можете подобрать каждый второй коробке. Вы даже можете подобрать каждое третье окно с торца. Эта величина называется шагом. Это означает разрыв между вашими последовательными пикапов. Размер шага должен быть положительным, если вы выбираете коробок от начала до конца и наоборот.
In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']
In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']
In [144]: alpha[1:5:-2]
Out[144]: []
In [145]: alpha[-1:-5:2]
Out[145]: []
Как В Python Вычисляет Недостающие Параметры:
При нарезке, если вы пропустите любой параметр, питон пытается определить его автоматически.
Если вы просмотрите исходный код с CPython, вы найдете функцию PySlice_GetIndicesEx (), который определяет показатели на срез по любым заданным параметрам. Вот это логический эквивалент кода в Python.
Эта функция принимает объект Python и необязательных параметров для нарезки и возвращает пуск, стоп, шаг, и нарезать длиной для запрошенного фрагмента.
def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):
length = len(obj)
if step is None:
step = 1
if step == 0:
raise Exception("Step cannot be zero.")
if start is None:
start = 0 if step > 0 else length - 1
else:
if start < 0:
start += length
if start < 0:
start = 0 if step > 0 else -1
if start >= length:
start = length if step > 0 else length - 1
if stop is None:
stop = length if step > 0 else -1
else:
if stop < 0:
stop += length
if stop < 0:
stop = 0 if step > 0 else -1
if stop >= length:
stop = length if step > 0 else length - 1
if (step < 0 and stop >= start) or (step > 0 and start >= stop):
slice_length = 0
elif step < 0:
slice_length = (stop - start + 1)/(step) + 1
else:
slice_length = (stop - start - 1)/(step) + 1
return (start, stop, step, slice_length)
Это интеллект, который присутствует за кружочками. Так как у Python есть встроенная функция среза, можно передавать некоторые параметры и увидеть, как лихо он вычисляет недостающие параметры.
In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [22]: s = slice(None, None, None)
In [23]: s
Out[23]: slice(None, None, None)
In [24]: s.indices(len(alpha))
Out[24]: (0, 6, 1)
In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]
In [26]: s = slice(None, None, -1)
In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]
In [28]: s = slice(None, 3, -1)
In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]
Примечание: этот пост был написан в мой блог, разведки за срезы на Python.
Это только для какой-то дополнительной информации... Рассмотрим список ниже
>>> l=[12,23,345,456,67,7,945,467]
Несколько других трюков для реверсирования списка:
>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]
>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]
Как правило, написание кода с жестко закодированные значения индекса приводит к читабельности и бардак в обслуживании. Например, если вы вернетесь к коду через год, вы будете смотрю и удивляюсь, что ты думал, когда писал это. Решение показано это просто способ более четко о том, что ваш код на самом деле делает. В общем, встроенный метод Slice() создает объект-фрагмент, который может быть использован в любом месте кусочек допускается. Например:
>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]
Если у вас есть экземпляр фрагмента, вы можете получить более подробную информацию об этом, глядя на ее С. пуск, ы.стоп, и S.шаг атрибутами, соответственно. Например:
а = кусочек(10, 50, 2) а.начать 10 а.остановка 50 а.шаг 2
Чтобы сделать его простым, помню фрагмент имеет только одну форму:
s[start:end:step]
и вот как это работает:
ы
: объект, который может быть нарезанЕще главное: все начало
,конец
, шаг
может быть опущен! И если они не указаны, их будет использовано значение по умолчанию: 0
,лен(ы)
,1
соответственно.
Итак, возможные варианты:
# Mostly used variations
s[start:end]
s[start:]
s[:end]
# Step-related variations
s[:end:step]
s[start::step]
s[::step]
# Make a copy
s[:]
Примечание: Если запустить >= конца (учитывая только тогда, когда шаг>0), Python будет возвращать пустой кусочек
[]`.
Эта часть объясняет основные особенности, как срез работает, и будет работать в большинстве случаев. Однако, там могут быть подводные камни нужно обращать внимание, и это отчасти объясняет их.
Первое, что смущает изучающих язык Python, что индекс может быть отрицательным! Дон'т паники: отрицательный индекс означает обратный отсчет.
Например:
s[-5:] # Start at the 5th index from the end of array,
# thus returning the last 5 elements.
s[:-5] # Start at index 0, and end until the 5th index from end of array,
# thus returning s[0:len(s)-5].
Делая вещи более запутанной, что " шаг " может быть тоже отрицательный!
Отрицательный шаг означает массив в обратном направлении: от конца до начала, с конца индекса и индекса начало исключается из результата.
Примечание: если приращение отрицательное, то значение по умолчанию для начала
это лен(ы)
(а конец
не равно 0
, потому что[::-1]содержит
и S[0]`). Например:
s[::-1] # Reversed slice
s[len(s)::-1] # The same as above, reversed slice
s[0:len(s):-1] # Empty list
Удивлюсь: кусок не поднять IndexError, если индекс находится вне диапазона!
Если индекс находится вне диапазона, Python будет пытаться все возможное, чтобы установить указатель на 0
или `лен(ов) в зависимости от ситуации. Например:
s[:len(s)+5] # The same as s[:len(s)]
s[-len(s)-5::] # The same as s[0:]
s[len(s)+5::-1] # The same as s[len(s)::-1], and the same as s[::-1]
Позвольте's отделка этот ответ с примерами, объясняющими все, что мы обсуждали:
# Create our array for demonstration
In [1]: s = [i for i in range(10)]
In [2]: s
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: s[2:] # From index 2 to last index
Out[3]: [2, 3, 4, 5, 6, 7, 8, 9]
In [4]: s[:8] # From index 0 up to index 8
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7]
In [5]: s[4:7] # From index 4 (included) up to index 7(excluded)
Out[5]: [4, 5, 6]
In [6]: s[:-2] # Up to second last index (negative index)
Out[6]: [0, 1, 2, 3, 4, 5, 6, 7]
In [7]: s[-2:] # From second last index (negative index)
Out[7]: [8, 9]
In [8]: s[::-1] # From last to first in reverse order (negative step)
Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [9]: s[::-2] # All odd numbers in reversed order
Out[9]: [9, 7, 5, 3, 1]
In [11]: s[-2::-2] # All even numbers in reversed order
Out[11]: [8, 6, 4, 2, 0]
In [12]: s[3:15] # End is out of range, and Python will set it to len(s).
Out[12]: [3, 4, 5, 6, 7, 8, 9]
In [14]: s[5:1] # Start > end; return empty list
Out[14]: []
In [15]: s[11] # Access index 11 (greater than len(s)) will raise an IndexError
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-15-79ffc22473a3> in <module>()
----> 1 s[11]
IndexError: list index out of range
Предыдущие ответы, Дон't обсуждают многомерный массив нарезки, которые можно использовать известные включает пакет:
Нарезка также может быть применен к многомерным массивам.
# Here, a is a NumPy array
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
>>> a[:2, 0:3:2]
array([[1, 3],
[5, 7]])
В ":2
" и до запятой работает на первом измерении и "0:3:2 в
" после запятой работает на втором измерении.
#!/usr/bin/env python
def slicegraphical(s, lista):
if len(s) > 9:
print """Enter a string of maximum 9 characters,
so the printig would looki nice"""
return 0;
# print " ",
print ' '+'+---' * len(s) +'+'
print ' ',
for letter in s:
print '| {}'.format(letter),
print '|'
print " ",; print '+---' * len(s) +'+'
print " ",
for letter in range(len(s) +1):
print '{} '.format(letter),
print ""
for letter in range(-1*(len(s)), 0):
print ' {}'.format(letter),
print ''
print ''
for triada in lista:
if len(triada) == 3:
if triada[0]==None and triada[1] == None and triada[2] == None:
# 000
print s+'[ : : ]' +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] == None and triada[2] != None:
# 001
print s+'[ : :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] == None:
# 010
print s+'[ :{0:2d} : ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] == None and triada[1] != None and triada[2] != None:
# 011
print s+'[ :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] == None:
# 100
print s+'[{0:2d} : : ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] == None and triada[2] != None:
# 101
print s+'[{0:2d} : :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] == None:
# 110
print s+'[{0:2d} :{1:2d} : ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif triada[0] != None and triada[1] != None and triada[2] != None:
# 111
print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
elif len(triada) == 2:
if triada[0] == None and triada[1] == None:
# 00
print s+'[ : ] ' + ' = ', s[triada[0]:triada[1]]
elif triada[0] == None and triada[1] != None:
# 01
print s+'[ :{0:2d} ] '.format(triada[1]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] == None:
# 10
print s+'[{0:2d} : ] '.format(triada[0]) + ' = ', s[triada[0]:triada[1]]
elif triada[0] != None and triada[1] != None:
# 11
print s+'[{0:2d} :{1:2d} ] '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]]
elif len(triada) == 1:
print s+'[{0:2d} ] '.format(triada[0]) + ' = ', s[triada[0]]
if __name__ == '__main__':
# Change "s" to what ever string you like, make it 9 characters for
# better representation.
s = 'COMPUTERS'
# add to this list different lists to experement with indexes
# to represent ex. s[::], use s[None, None,None], otherwise you get an error
# for s[2:] use s[2:None]
lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]]
slicegraphical(s, lista)
Вы можете запустить этот скрипт и экспериментировать с ним, ниже некоторые образцы, которые я получил от сценария.
+---+---+---+---+---+---+---+---+---+
| C | O | M | P | U | T | E | R | S |
+---+---+---+---+---+---+---+---+---+
0 1 2 3 4 5 6 7 8 9
-9 -8 -7 -6 -5 -4 -3 -2 -1
COMPUTERS[ 4 : 7 ] = UTE
COMPUTERS[ 2 : 5 : 2 ] = MU
COMPUTERS[-5 : 1 :-1 ] = UPM
COMPUTERS[ 4 ] = U
COMPUTERS[-4 :-6 :-1 ] = TU
COMPUTERS[ 2 :-3 : 1 ] = MPUT
COMPUTERS[ 2 :-3 :-1 ] =
COMPUTERS[ : :-1 ] = SRETUPMOC
COMPUTERS[-5 : ] = UTERS
COMPUTERS[-5 : 0 :-1 ] = UPMO
COMPUTERS[-5 : :-1 ] = UPMOC
COMPUTERS[-1 : 1 :-2 ] = SEUM
[Finished in 0.9s]
При использовании отрицательного шага, заметьте, что ответ сдвигается вправо на 1.