Понимание обозначения среза

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

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

Он выглядит чрезвычайно мощным, но я не совсем обнял его.

Ответ 1

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

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(stop) также ведут себя немного по-разному в зависимости от количества аргументов, аналогично range(), т.е. поддерживаются как slice(stop) и slice(start, stop[, step]). Чтобы пропустить указание заданного аргумента, можно использовать None, так что, например, a[start:] эквивалентно a[slice(start, None)] или a[::-1] эквивалентно a[slice(None, None, -1)].

В то время как : -based нотация очень полезно для простой нарезки, явное использование slice() объектов упрощает программную генерацию нарезания.

Ответ 2

Python tutorial говорит об этом (прокрутите немного вниз, пока не дойдете до части, касающейся нарезки).

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

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

Один из способов вспомнить, как работают срезы, - это учитывать индексы как указывающие между символами, а левый край первого символа нумеруется 0. Тогда правый край последнего символа строки из n символов имеет индекс n.

Ответ 3

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

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

Если 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)'

Ответ 4

Ответы выше не обсуждают назначение срезов. Чтобы понять назначение срезов, полезно добавить еще одну концепцию в искусство 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, легко обойти голову при индексации пустого фрагмента:

>>> 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), вставленные элементы всегда располагаются прямо напротив "o", даже когда мы назначаем пустой срез. Таким образом, позиция для пустого назначения слайса является логическим расширением позиций для непустых назначений слайса.

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

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

Фактически, по сравнению с индексированием, нарезка Python причудливо защищена от ошибок:

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

Это также может прояснить разницу между нарезкой и индексацией.

Ответ 5

Объяснить нотацию фрагмента 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 отрицательный, stop значение по умолчанию - -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.)

Когда step отрицательный, значения по умолчанию для start и stop изменения

По умолчанию, когда аргумент step пуст (или None), ему присваивается значение +1.

Но вы можете передать отрицательное целое число, и список (или большинство других стандартных slicables) будет разрезан с конца до начала.

Таким образом, отрицательный срез изменит значения по умолчанию для start и stop !

Подтверждение этого в источнике

Мне нравится поощрять пользователей читать источник, а также документацию. Исходный код для объектов среза и эта логика находятся здесь. Сначала мы определяем, является ли step отрицательным:

 step_is_negative = step_sign < 0;

Если это так, нижняя граница -1 означает, что мы -1 весь путь вплоть до начала включительно, а верхняя граница - это длина минус 1, то есть мы начинаем в конце. (Обратите внимание, что семантика этого -1 отличается от -1 что пользователи могут передавать индексы в Python с указанием последнего элемента.)

if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}

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

else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

Тогда нам может потребоваться применить значения по умолчанию для start и stop - значение по умолчанию для start вычисляется как верхняя граница, когда step отрицательный:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}

и stop, нижняя граница:

if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}

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

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

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

last_nine_slice = slice(-9, None)

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

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

>>> 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. Обычно вы хотите перебирать фрагмент, а не просто создавать его статически в памяти. islice идеально подходит для этого. Предостережение, оно не поддерживает отрицательные аргументы для start, stop или step, поэтому, если это проблема, вам может понадобиться рассчитать индексы или перевернуть итерируемый заранее.

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]

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

Ответ 6

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

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

Ответ 7

В 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
             a    s    t   r    i   n   g
    -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]

Ответ 8

Нашел эту отличную таблицу в 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)

Ответ 9

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

(from:to:step)

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

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

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

В любом случае это работает для меня...

Ответ 10

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

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

def range(start=0, stop, step=1):  # Illegal syntax, but that 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 (step)> 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] - это просто вся строка.

Ответ 11

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

Ответ 12

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

mylist[X:Y]

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

Ответ 13

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

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

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

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

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

Ответ 14

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

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

Ответ 15

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

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

В Wiki Python есть удивительная картина, которая четко различает индексацию и нарезку.

Enter image description here

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

Индексирование похоже на работу с содержимым коробки. Вы можете проверить содержимое любого ящика. Но вы не можете проверить содержимое нескольких ящиков одновременно. Вы даже можете заменить содержимое коробки. Но вы не можете поместить два шара в одну коробку или заменить два шара одновременно.

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 определяет недостающие параметры:

При нарезке, если вы пропустите какой-либо параметр, 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 есть встроенная функция slice, вы можете передать некоторые параметры и проверить, насколько разумно он рассчитывает отсутствующие параметры.

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.

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

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

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

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

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

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]

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

Ответ 19

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

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

# 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" после запятой работает во втором измерении.

Ответ 20

#!/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)

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

  +---+---+---+---+---+---+---+---+---+
  | 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.

Ответ 21

Мой мозг, похоже, рад принять, что 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.

Ответ 22

Большинство предыдущих ответов проясняют вопросы об обозначениях срезов.

Синтаксис расширенного индексирования, используемый для нарезки, - aList[start:stop:step], и основные примеры:

Enter image description here:

Больше примеров нарезки: 15 расширенных фрагментов

Ответ 23

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

variable[number1:number2]

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

Ответ 24

В Python наиболее простой формой для нарезки является следующее:

l[start:end]

где l - это некоторая коллекция, start - это инклюзивный индекс, а end - эксклюзивный индекс.

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]

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

In [5]: l[:3] == l[0:3]
Out[5]: True

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

Отрицательные целые числа полезны при выполнении смещений относительно конца коллекции:

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 three elements
Out[8]: [7, 8, 9]

При нарезке можно указать индексы, выходящие за пределы, такие как:

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

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

In [16]: l[2:6] = list('abc') # Assigning fewer 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]

Если вы пропустите начальный и конечный индексы, вы создадите копию коллекции:

In [14]: l_copy = l[:]

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

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

In [20]: l[:] = list('hello...')

In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']

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

l[start:end:step]

где l - это коллекция, start - это инклюзивный индекс, end - это эксклюзивный индекс, а step - это шаг, который можно использовать для получения каждого n-го элемента в 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]

Использование step предоставляет полезную хитрость для обращения коллекции в Python:

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

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

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

Однако использование отрицательного значения для step может привести к путанице. Кроме того, чтобы быть Pythonic, вы должны избегать использования start, end и step в одном слайсе. В случае, если это требуется, попробуйте сделать это в двух заданиях (одно для нарезки, а другое для продвижения).

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]

Ответ 25

Я хочу добавить один Hello, World! Пример, объясняющий основы ломтиков для самых начинающих. Это мне очень помогло.

Пусть есть список с шестью значениями ['P', 'Y', 'T', 'H', 'O', 'N']:

+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
  0   1   2   3   4   5

Теперь простейшими срезами этого списка являются его подсписки. Обозначение - [<index>:<index>], и ключ должен прочитать это как это:

[ start cutting before this index : end cutting before this index ]

Теперь, если вы сделаете фрагмент [2:5] из списка выше, это произойдет:

        |           |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
  0   1 | 2   3   4 | 5

Вы сделали разрез перед элементом с индексом 2 и еще один разрез перед элементом с индексом 5. Таким образом, результатом будет срез между этими двумя срезами, список ['T', 'H', 'O'].

Ответ 26

Ниже приведен пример индекса строки:

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

str="Name string"

Пример нарезки: [начало: конец: шаг]

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

Ниже приведен пример использования:

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

Ответ 27

На мой взгляд, вы лучше поймете и запомните нотацию Python для разрезания строк, если посмотрите на нее следующим образом (читайте дальше).

Давайте работать со следующей строкой...

azString = "abcdefghijklmnopqrstuvwxyz"

Для тех, кто не знает, вы можете создать любую подстроку из azString, используя обозначение azString[x:y]

Исходя из других языков программирования, это когда здравый смысл скомпрометирован. Что такое х и у?

Мне пришлось сесть и запустить несколько сценариев в своем поиске техники запоминания, которая поможет мне вспомнить, что такое x и y, и поможет мне правильно нарезать строки с первой попытки.

Мой вывод заключается в том, что x и y следует рассматривать как граничные индексы, которые окружают строки, которые мы хотим добавить. Таким образом, мы должны видеть выражение как azString[index1, index2] или даже более ясно как azString[index_of_first_character, index_after_the_last_character].

Вот пример визуализации этого...

Letters   a b c d e f g h i j ...
         ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
Indexes  0 1 2 3 4 5 6 7 8 9 ...
             |           |
cdefgh    index1       index2

Итак, все, что вам нужно сделать, это установить index1 и index2 в значения, которые будут окружать желаемую подстроку. Например, чтобы получить подстроку "cdefgh", вы можете использовать azString[2:8], потому что индекс слева от "c" равен 2, а индекс справа от "h" равен 8.

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

a b [ c d e f g h ] i j

Этот трюк работает постоянно и его легко запомнить.

Ответ 28

Если вы чувствуете, что отрицательные индексы в разрезании вводят в заблуждение, вот очень простой способ подумать об этом: просто замените отрицательный индекс на len - index. Например, замените -3 на len(list) - 3.

Лучший способ проиллюстрировать, что делает срезание внутри, - просто показать это в коде, который реализует эту операцию:

def slice(list, start = None, end = None, step = 1):
  # Take care of missing start/end parameters
  start = 0 if start is None else start
  end = len(list) if end is None else end

  # Take care of negative start/end parameters
  start = len(list) + start if start < 0 else start
  end = len(list) + end if end < 0 else end

  # Now just execute a for-loop with start, end and step
  return [list[i] for i in range(start, end, step)]

Ответ 29

Slice: - рядом с вашей ногой появляется змея. Он движется от невидимого до видимого. Наше видение показывает (как срез) только часть мира. Аналогично, фрагмент Python извлекает элементы, основанные на запуске и остановке. Мы берем фрагменты на многих типах в Python. Мы указываем необязательный первый индекс, необязательный последний индекс и необязательный шаг.

values[1:3]  Index 1 through index 3.
values[2:-1] Index 2 through index one from last.
values[:2]   Start through index 2.
values[2:]   Index 2 through end.
values[::2]  Start through end, skipping ahead 2 places each time.

вы можете получить хорошие примеры по ссылке ниже: пример обозначения фрагмента питона

Ответ 30

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

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

Создайте два списка для нарезки. Первый - это числовой список от 1 до 9 (список А). Второй также представляет собой числовой список от 0 до 9 (список B):

A = list(range(1, 10, 1)) # Start, stop, and step
B = list(range(9))

print("This is List A:", A)
print("This is List B:", B)

Индексируйте число 3 от A и число 6 от B.

print(A[2])
print(B[6])

Базовая нарезка

Расширенный синтаксис индексации, используемый для нарезки, - это aList [start: stop: step]. Аргумент start и шаг по умолчанию равны none - единственным обязательным аргументом является stop. Вы заметили, что это похоже на то, как диапазон использовался для определения списков A и B? Это связано с тем, что объект слайса представляет собой набор индексов, заданных диапазоном (начало, остановка, шаг). Документация по Python 3.4.

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

Важно отметить, что первый элемент - это индекс 0, а не индекс 1. Именно поэтому мы используем 2 списка для этого упражнения. Элементы списка A нумеруются в соответствии с порядковым положением (первый элемент равен 1, второй элемент равен 2 и т.д.), А элементы списка B представляют собой числа, которые будут использоваться для их индексации ([0] для первого элемента 0, и т.д.).

С расширенным синтаксисом индексации мы получаем диапазон значений. Например, все значения извлекаются с помощью двоеточия.

A[:]

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

Учитывая шаблон aList [start: stop], получить первые два элемента из списка А.