Объяснить нотацию фрагмента

Мне нужно хорошее объяснение (ссылки – плюс) в нотации Python.

Для меня эта нотация требует немного поднять.

  • Добавить SUM значений двух LISTS в новый СПИСОК
  • Разделение вложенного списка на два списка
  • В Python, как я могу найти индекс первого элемента в списке, который НЕ является некоторым значением?
  • Что означает locals () '] в Python?
  • Почему «.sort ()» вызывает список «None» в Python?
  • Убедитесь, что длина строки матрицы одинакова (python3)
  • Он выглядит чрезвычайно мощным, но я не совсем обнял его.

  • Как переключить положение двух элементов в списке Python?
  • Добавить SUM значений двух LISTS в новый СПИСОК
  • странное поведение со списком словарей в python
  • сравнить два списка в python и вернуть индексы согласованных значений
  • Базовые индексирующие рекурсии подстроки в строке (python)
  • Извлечение элементов списка на нечетных позициях
  • 24 Solutions collect form web for “Объяснить нотацию фрагмента”

    Это довольно просто:

    a[start:end] # items start through end-1 a[start:] # items start through the rest of the array a[:end] # items from the beginning through end-1 a[:] # a copy of the whole array 

    Существует также значение step , которое можно использовать с любым из вышеперечисленных способов:

     a[start:end:step] # start through not past end, by step 

    Ключевым моментом для запоминания является то, что :end value представляет первое значение, которое не находится в выбранном фрагменте. Таким образом, разница между end и start – это количество выбранных элементов (если step равен 1, по умолчанию).

    Другая особенность заключается в том, что start или end может быть отрицательным числом, что означает, что он отсчитывается от конца массива, а не от начала. Так:

     a[-1] # last item in the array a[-2:] # last two items in the array a[:-2] # everything except the last two items 

    Python добр к программисту, если есть меньше предметов, чем вы просите. Например, если вы запрашиваете a[:-2] и только один элемент, вы получаете пустой список вместо ошибки. Иногда вы предпочитаете ошибку, поэтому вы должны знать, что это может произойти.

    В учебнике 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]] 

    Конечно, если (high-low)%stride != 0 , то конечная точка будет немного ниже high-1 .

    Расширенные нарезки (с запятыми и эллипсами) в основном используются только специальными структурами данных (например, Numpy); основные последовательности не поддерживают их.

     >>> class slicee: ... def __getitem__(self, item): ... return `item` ... >>> slicee()[0, 1:2, ::5, ...] '(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)' 

    В приведенных выше ответах не обсуждается назначение среза:

     >>> 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] ) делают нотацию среза – которая имеет необязательные аргументы, start , stop , step :

     sliceable[start:stop:step] 

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

    Важные определения

    Прежде всего, давайте определим несколько терминов:

    start: начальный индекс среза, он будет включать элемент в этот индекс, если он не будет таким же, как stop , по умолчанию 0, то есть первый индекс. Если это отрицательно, это означает, что вы начинаете n пунктов с конца.

    stop: конечный индекс среза, он не включает элемент в этот индекс, по умолчанию длина фрагментированной последовательности, то есть до и включая конец.

    step: количество, на которое увеличивается индекс, по умолчанию – 1. Если он отрицательный, вы нарезаете итерабельность в обратном порядке.

    Как работает индексирование

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

      +---+---+---+---+---+---+ | 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, on»)

    Объяснение:

    Полная запись

     my_list[-9:None:None] 

    и для замены значений по умолчанию (фактически, когда step отрицательный, по умолчанию -len(my_list) - 1 , поэтому None для остановки на самом деле просто означает, что он идет в зависимости от того, какой конечный шаг принимает его):

     my_list[-9:len(my_list):1] 

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

     list_copy = sequence[:] 

    И их очистка:

     del my_list[:] 

    (Python 3 получает метод list.copy и list.clear .)

    Дайте своим фрагментам описательное имя!

    Вы можете счесть полезным отделить формирование среза от его передачи до метода list.__getitem__ (это то, что делают квадратные скобки ). Даже если вы не новичок в этом, он сохраняет ваш код более читабельным, так что другие, которые могут читать ваш код, могут более легко понять, что вы делаете.

    Однако вы не можете просто назначить переменную целые числа, разделенные двоеточиями. Вам нужно использовать объект среза:

     last_nine_slice = slice(-9, None) 

    Второй аргумент – None , так что первый аргумент интерпретируется как start аргумент, иначе он будет аргументом stop .

    Затем вы можете передать объект среза в свою последовательность:

     >>> list(range(100))[last_nine_slice] [91, 92, 93, 94, 95, 96, 97, 98, 99] 

    Вопросы памяти:

    Поскольку фрагменты списков Python создают новые объекты в памяти, другая важная функция, о которой нужно знать, – itertools.islice . Обычно вы хотите перебирать фрагмент, а не просто создавать его статически в памяти. islice идеально подходит для этого. Предостережение, оно не поддерживает отрицательные аргументы для start , stop или step , поэтому, если это проблема, вам может потребоваться рассчитать индексы или перевернуть итерируемый заранее.

     >>> length = 100 >>> last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1) >>> list_last_nine = list(last_nine) >>> list_last_nine [91, 92, 93, 94, 95, 96, 97, 98, 99] 

    Тот факт, что список фрагментов создает копию, является особенностью самих списков. Если вы перерезаете продвинутые объекты, такие как Pandas DataFrame, он может вернуть представление на оригинале, а не на копию.

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

     >>> 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] 

    Нашел эту замечательную таблицу на странице http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

     Python indexes and slices for a six-element list. Indexes enumerate the elements, slices enumerate the spaces between the elements. Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5] Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4] +---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3] | a | b | c | d | e | f | a[5]==5 a[1:2]==[1] +---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4] Slice from front: : 1 2 3 4 5 : a[-2]==4 Slice from rear: : -5 -4 -3 -2 -1 : b=a[:] b==[0,1,2,3,4,5] (shallow copy of a) 

    В 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 

    Когда вы говорите [a: b: c], вы говорите в зависимости от знака c (вперед или назад), начинайте с a и заканчивая на b (исключая элемент в bth-индексе). Используйте правило индексирования выше и помните, что вы найдете только элементы в этом диапазоне:

     -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 astring -9 -8 -7 -6 -5 -4 -3 -2 -1 

    Если ваш выбор a, b и c позволяет перекрываться с диапазоном выше, когда вы проходите с использованием правил для a, 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] 

    После использования этого я понимаю, что самое простое описание состоит в том, что оно точно такое же, как и аргументы в цикле for …

     (from:to:step) 

    любой из них является необязательным

     (:to:step) (from::step) (from:to) 

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

    Это все равно работает для меня …

    Мне легче запомнить, как это работает, тогда я могу выяснить какую-либо конкретную комбинацию пуска / остановки / шага.

    Поучительно понять range() :

     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 

    Начните с start , шаг за step , не доходите до stop . Очень просто.

    Вещь, которую следует помнить об отрицательном шаге, заключается в том, что stop всегда является исключенным концом, будь то выше или ниже. Если вы хотите, чтобы один и тот же фрагмент был в противоположном порядке, намного проще сделать разворот отдельно: например, 'abcde'[1:-2][::-1] срезает один символ слева, два справа, а затем меняет направление. (См. Также reversed() .)

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

    TODO : в приведенном ниже коде была ошибка с «никогда не выходить за пределы последовательности», когда abs (шаг)> 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] 

    Не беспокойтесь о том, is None данных – просто помните, что опускание start и / или stop всегда делает правильную вещь, чтобы дать вам целую последовательность.

    Нормализованные отрицательные индексы сначала позволяют запускать и / или останавливаться независимо от конца: 'abcde'[1:-2] == 'abcde'[1:3] == 'bc' несмотря на range(1,-2) == [] . Нормализацию иногда называют «по модулю длины», но обратите внимание, что она добавляет длину только один раз: например, 'abcde'[-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

    Обозначение разреза Python:

     a[start:end:step] 
    • Для start и end отрицательные значения интерпретируются как относящиеся к концу последовательности.
    • Положительные индексы для end указывают позицию после включения последнего элемента.
    • Пустые значения по умолчанию заданы следующим образом: [+0:-0:1] .
    • Использование отрицательного шага отменяет интерпретацию start и end

    Обозначение распространяется на (numpy) матрицы и многомерные массивы. Например, чтобы разрезать целые столбцы, вы можете использовать:

     m[::,0:2:] ## slice the first two columns 

    В срезах хранятся ссылки, а не копии элементов массива. Если вы хотите сделать отдельную копию массива, вы можете использовать deepcopy() .

    Я сам использую метод «указательные точки между элементами», но один способ описать его, который иногда помогает другим, заключается в следующем:

     mylist[X:Y] 

    X – это индекс первого элемента, который вы хотите.
    Y – индекс первого элемента, которого вы не хотите.

    Это просто дополнительная информация … Рассмотрим приведенный ниже список

     >>> 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] 

    См. Ответ abc выше

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

     r = [1, 'blah', 9, 8, 2, 3, 4] >>> r[1:4] = [] >>> r [1, 2, 3, 4] 

    Вот как я преподаю кусочки новичков:

    Понимание различий между индексацией и нарезкой:

    Wiki Python обладает этой удивительной картиной, которая четко отличает индексирование и нарезку.

    введите описание изображения здесь

    Это список с 6 элементами в нем. Чтобы лучше понять нарезку, рассмотрите этот список как набор из шести ящиков, расположенных вместе. В каждой коробке есть алфавит.

    Индексация – это дело с содержимым окна. Вы можете проверить содержимое любой коробки. Но вы не можете проверить содержимое нескольких ящиков одновременно. Вы даже можете заменить содержимое поля. Но вы не можете поместить 2 мяча в 1 коробку или заменить 2 мяча за раз.

     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 

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

    Вы можете даже забрать первые 3 коробки или последние 2 коробки или все коробки между 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 показывает отсутствующие параметры:

    При разрезе, если вы не укажете какой-либо параметр, 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] 

    Примечание: Эта запись изначально написана в моем блоге http://www.avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html

    Как правило, при написании кода с большим количеством жестко закодированных значений индекса возникает недопустимость чтения и обслуживания. Например, если вы вернетесь к коду через год, вы посмотрите на него и зададитесь вопросом, что вы думаете, когда вы его написали. Вышеприведенное решение – это просто способ более четко указать, что делает ваш код. В общем, встроенный 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.start, s.stop и s.step, соответственно. Например:

     >>> a = slice(10, 50, 2) >>> a.start 10 >>> a.stop 50 >>> a.step 2 >>> 

    1. Обозначение фрагмента

    Чтобы сделать это простым, помните, что срез имеет только одну форму:

     s[start:end:step] 

    и вот как это работает:

    • s : объект, который можно нарезать
    • start : первый индекс для начала итерации
    • end : последний индекс, ПРИМЕЧАНИЕ, что end индекс не будет включен в полученный фрагмент
    • step : выбрать элемент каждый step индекса

    Еще одна вещь для импорта: все start , end , step можно опустить! И если они опущены, их значение по умолчанию будет использовано: 0 , len(s) , 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[:] 

    ПРИМЕЧАНИЕ. Если start>=end (учитывается только при step>0 ), python вернет пустой фрагмент [] .

    2. Ловушки

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

    Отрицательные индексы

    Самое первое, что смущает учеников python, – это то, что индекс может быть отрицательным! Не паникуйте: отрицательный индекс означает подсчет с обратной стороны.

    Например:

     s[-5:] # start at the 5th index from the end of array, # thus returns the last 5 elements s[:-5] # start at index 0, end until the 5th index from end of array, # thus returns s[0:len(s)-5] 

    Отрицательный шаг

    Сделать вещи более запутанным является то, что step может быть отрицательным тоже!

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

    ПРИМЕЧАНИЕ : когда шаг отрицательный, значение по умолчанию для start len(s) (в то время как end не равен 0 , потому что s[::-1] содержит s[0] ). Например:

     s[::-1] # reversed slice s[len(s)::-1] # same as above, reversed slice s[0:len(s):-1] # empty list 

    Ошибка вне диапазона?

    Будьте удивлены: срез не вызывает IndexError, когда индекс выходит за пределы диапазона!

    Если индекс находится за пределами допустимого диапазона, python попытается наилучшим образом установить индекс в 0 или len(s) соответствии с ситуацией. Например:

     s[:len(s)+5] # same as s[:len(s)] s[-len(s)-5::] # same as s[0:] s[len(s)+5::-1] # same as s[len(s)::-1], same as s[::-1] 

    3. Примеры

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

     # 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, 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 IndexError --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-15-79ffc22473a3> in <module>() ----> 1 s[11] IndexError: list index out of range 

    Мой мозг, похоже, рад принять, что lst[start:end] содержит start -го элемента. Я мог бы даже сказать, что это «естественное предположение».

    Но иногда возникает сомнение, и мой мозг требует подтверждения того, что он не содержит end элемента.

    В эти моменты я полагаюсь на эту простую теорему:

     for any n, lst = lst[:n] + lst[n:] 

    Это довольно свойство говорит мне, что lst[start:end] не содержит end -th элемент, потому что он находится в lst[end:] .

    Заметим, что эта теорема верна для любого n . Например, вы можете проверить, что

     lst = range(10) lst[:-42] + lst[-42:] == lst 

    возвращает значение True .

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

     variable[number1:number2] 

    В этом примере положительное число для числа 1 – сколько компонентов вы снимаете спереди. Отрицательное число – это полная противоположность, сколько вы держите от конца. Положительное число для числа 2 указывает, сколько компонентов вы намерены сохранить с самого начала, а отрицательным является то, сколько вы намерены взлететь с конца. Это несколько контрастно интуитивно, но вы правы, полагая, что нарезка списка чрезвычайно полезна.

    В приведенных выше ответах не обсуждаются многомерные массивные срезы, которые можно использовать в знаменитом пакете numpy:

    Нарезка также применяется к многомерным массивам.

     >>> 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] 

    When using a negative step, notice that the answer is shifted to the right by 1.

    In Python, the most basic form for slicing is the following:

    l[start:end]

    where l is some collection, start is an inclusive index and end is an exclusive index.

     In [1]: l = list(range(10)) In [2]: l[:5] # first five elements Out[2]: [0, 1, 2, 3, 4] In [3]: l[-5:] # last five elements Out[3]: [5, 6, 7, 8, 9] 

    When slicing from start, you can omit the zero index, and when slicing to the end, you can omit the final index since it is redundant, so do not be verbose:

     In [5]: l[:3] == l[0:3] Out[5]: True In [6]: l[7:] == l[7:len(l)] Out[6]: True 

    Negative integers are useful when doing offsets relative to the end of a collection:

     In [7]: l[:-1] # include all elements but the last one Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8] In [8]: l[-3:] # take the last 3 elements Out[8]: [7, 8, 9] 

    It is possible to provide indices that are out of bounds when slicing such as:

     In [9]: l[:20] # 20 is out of index bounds, l[20] will raise an IndexError exception Out[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [11]: l[-20:] # -20 is out of index bounds, l[-20] will raise an IndexError exception Out[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

    Keep in mind that the result of slicing a collection is a whole new collection. In addition, when using slice notation in assignments, the length of the slice assignment do not need to be the same. The values before and after the assigned slice will be kept, and the collection will shrink or grow to contain the new values:

     In [16]: l[2:6] = list('abc') # assigning less elements than the ones contained in the sliced collection l[2:6] In [17]: l Out[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9] In [18]: l[2:5] = list('hello') # assigning more elements than the ones contained in the sliced collection l [2:5] In [19]: l Out[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9] 

    If you omit the start and end index, you will make a copy of the collection:

     In [14]: l_copy = l[:] In [15]: l == l_copy and l is not l_copy Out[15]: True 

    If the start and end indexes are omitted when performing an assignment operation, the entire content of the collection will be replaced with a copy of what is referenced:

     In [20]: l[:] = list('hello...') In [21]: l Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.'] 

    Besides basic slicing, it is also possible to apply the following notation:

     l[start:end:step] 

    where l is a collection, start is an inclusive index, end is an exclusive index, and step is a stride that can be used to take every nth item in l .

     In [22]: l = list(range(10)) In [23]: l[::2] # take the elements which indexes are even Out[23]: [0, 2, 4, 6, 8] In [24]: l[1::2] # take the elements which indexes are odd Out[24]: [1, 3, 5, 7, 9] 

    Using step provides a useful trick to reverse a collection in Python:

     In [25]: l[::-1] Out[25]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 

    It is also possible to use negative integers for step as the following example:

     In[28]: l[::-2] Out[28]: [9, 7, 5, 3, 1] 

    However, using a negative value for step could become very confusing. Moreover, in order to be Pythonic, you should avoid using start , end , and step in a single slice. In case this is required, consider doing this in two assignments (one to slice, and the other to stride).

     In [29]: l = l[::2] # this step is for striding In [30]: l Out[30]: [0, 2, 4, 6, 8] In [31]: l = l[1:-1] # this step is for slicing In [32]: l Out[32]: [2, 4, 6] 

    The below is the example of index of a string

      +---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1 str="Name string" 

    slicing example: [start:end:step]

     str[start:end] # items start through end-1 str[start:] # items start through the rest of the array str[:end] # items from the beginning through end-1 str[:] # a copy of the whole array 

    Below is the example usage

     print str[0]=N print str[0:2]=Na print str[0:7]=Name st print str[0:7:2]=Nm t print str[0:-1:2]=Nm ti 
    Python - лучший язык программирования в мире.