Как индексирование с X [i: j: k] работает для списка в Python [duplicate]

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

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

Он выглядит очень мощным, но я не совсем обнял его.

2411
задан codeforester 19 October 2017 в 17:12
поделиться

30 ответов

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

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

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

3123
ответ дан Nils Werner 16 August 2018 в 10:01
поделиться
  • 1
    Нарезка встроенных типов возвращает копию, но это не универсально. Примечательно, что разрезание массивов NumPy возвращает представление, которое разделяет память с оригиналом. – Beni Cherniavsky-Paskin 23 September 2013 в 01:13
  • 2
    Что бы это сделало? [::-2] Я пробовал, но я этого не понимаю. Например, с этим списком a = ['1', '2', '3', '4', '5']. – RodriKing 8 August 2018 в 16:37
  • 3
    @RodriKing Это означает, что ваше начало и конец пустые, а ваш шаг -2. Таким образом, вы меняете (потому что это отрицательно) и принимают по 2 элемента, для всего списка, потому что start и empty не определены. – mbh86 9 August 2018 в 09:54
  • 4
    Другой пример: a = list(range(100)) # [0,1,2, .... ,99] и a[20::-3] Это означает, что вы вернетесь назад 3 на 3. Вы начинаете с позиции 20 и идите 3 назад ... 20, 17, 14 и т. Д. ... – mbh86 9 August 2018 в 09:56
  • 5
    – Ciprian Tomoiagă 31 August 2018 в 10:39
  • 6
    – Greg Hewgill 13 September 2018 в 03:46
187
ответ дан Aaron Hall 16 August 2018 в 10:01
поделиться

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

>>> 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 выше

84
ответ дан abc 16 August 2018 в 10:01
поделиться
  • 1
    еще один интересный пример: a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2], который приводит к [9] – Deviacium 10 July 2017 в 13:59

Нашел эту большую таблицу в 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)
85
ответ дан AdrianoFerrari 16 August 2018 в 10:01
поделиться

Хехех, странно видеть, что я пытаюсь дать лучшее и более простое объяснение после 2600+ голосов на том, что было отмечено как правильный ответ от Grew Hewgill.

Здесь мы идем ...

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

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

azString = "abcdefghijklmnopqrstuvwxyz"

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

. Исходя из других языков программирования, здравый смысл скомпрометирован. Что такое 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.

Помните, что мы устанавливаем границы.

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

Hopefuly это поможет.

3
ответ дан asiby 16 August 2018 в 10:01
поделиться

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

Поучительно сначала понять 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] - это целая строка.

32
ответ дан Beni Cherniavsky-Paskin 16 August 2018 в 10:01
поделиться
  • 1
    this_is_how_slicing_works не совпадает с фрагментом питона. НАПРИМЕР. [0, 1, 2][-5:3:3] получит [0] в python, но list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3)) получит [1]. – Eastsun 29 October 2016 в 12:56
  • 2
    @ Eastsun К сожалению, вы правы! Более ясный случай: range(4)[-200:200:3] == [0, 3], но list(this_is_how_slicing_works([0, 1, 2, 3], -200, 200, 3)) == [2]. Моя if 0 <= i < len(seq): была попыткой реализовать "никогда не выходить за пределы последовательности" просто, но неправильно для шага & gt; 1. Я переписал его позже сегодня (с тестами). – Beni Cherniavsky-Paskin 30 October 2016 в 13:36

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

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

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

enter image description here [/g1]

Это список с 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

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

Вы даже можете забрать первые 3 ящика или последние 2 коробки или все ящики между 1 и am; 4. Итак, вы можете выбрать любой набор ящиков, если знаете начало & amp; окончание. Эти позиции называются start & amp; стоп-позиции.

Интересно, что вы можете сразу заменить несколько ящиков.

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 & amp; необязательные параметры для нарезки и начала возврата, остановки, шага & amp; длина среза для запрошенного фрагмента.

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, вы можете передать некоторые параметры & amp; проверьте, насколько он разумно вычисляет отсутствующие параметры.

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-интеллект-behind.html

24
ответ дан ChillarAnand 16 August 2018 в 10:01
поделиться

Нотация нарезания питона:

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

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

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

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

28
ответ дан Community 16 August 2018 в 10:01
поделиться

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

>>> 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]
125
ответ дан Dana 16 August 2018 в 10:01
поделиться

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

r = [1, 'blah', 9, 8, 2, 3, 4]
>>> r[1:4] = []
>>> r
[1, 2, 3, 4]
25
ответ дан dansalmo 16 August 2018 в 10:01
поделиться

Перечисление возможностей, разрешенных грамматикой:

>>> 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 `item`
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
313
ответ дан ephemient 16 August 2018 в 10:01
поделиться
  • 1
    происходит что-то странное, если stride отрицательно, как в [::-1]? – Charlie Parker 21 August 2017 в 16:16
  • 2
    @CharlieParker Когда strike отрицательно, он отсчитывает от high до low. – ephemient 21 August 2017 в 18:22
  • 3
    На самом деле все еще что-то осталось вне, например. если я наберу «яблоко» [4: -4: -1], я получаю «elp», python переводит -4 в 1, может быть? – liyuan 1 January 2018 в 17:39

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

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

Создайте два списка для среза, первый - числовой список от 1 до 9 (список A). Второй - также числовой список, от 0 до 9 (список B)

A = list(range(1,10,1)) # start,stop,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])

Основной Slicing

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

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

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

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

A[:]

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

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

0
ответ дан EstevaoLuis 16 August 2018 в 10:01
поделиться

Я хочу добавить один пример 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'].

4
ответ дан Jeyekomon 16 August 2018 в 10:01
поделиться

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

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

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

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

397
ответ дан kenorb 16 August 2018 в 10:01
поделиться
  • 1
    Для срезов с отрицательными шагами я нахожу это искусство ASCII запутанным, и оно должно распространяться на -6, поскольку 'ApleH'[:-6:-1] является допустимым срезом и отличается от использования -5 – Chris_Rands 26 July 2017 в 15:30
  • 2
    «Один из способов запоминания того, как работают срезы, - это учитывать индексы как указывающие между символами». - это отличный способ задуматься об этом – jusopi 8 August 2018 в 18:05

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

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

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

Можно предоставить индексы, которые выходят за рамки, когда таких как:

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]

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

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]

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

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 является эксклюзивным index и step - это шаг, который может использоваться для приема каждого пункта nth в 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]
7
ответ дан lmiguelvargasf 16 August 2018 в 10:01
поделиться
#!/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.

10
ответ дан mahmoh 16 August 2018 в 10:01
поделиться

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

variable[number1:number2]

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

11
ответ дан Obito 16 August 2018 в 10:01
поделиться
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 ​​

30
ответ дан Peter Mortensen 16 August 2018 в 10:01
поделиться
  • 1
    Спасибо за перечисление индексов; Меня смутило отсутствие «-0», но это очищает его, такая сила: D – harshvchawla 18 May 2017 в 03:48

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

 +---+---+---+---+---+
 | 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
6
ответ дан Prince Dhadwal 16 August 2018 в 10:01
поделиться
[Д0] 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. Pitfalls

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

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

Самое первое, что смущает учеников 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
20
ответ дан pylang 16 August 2018 в 10:01
поделиться
  • 1
    Похоже, у вас есть ошибка. Вы утверждаете, что s[::-1] совпадает с s[len(s):0:-1], но когда я пытаюсь с s=range(10), я вижу, что последний оставляет «0». из списка. – MrFlick 13 January 2017 в 18:12
  • 2
    @MrFlick Ты прав! Я сделал там ошибку, только что обновленный. – cizixs 16 January 2017 в 03:43

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

>>> a = slice(10, 50, 2)
>>> a.start
10
>>> a.stop
50
>>> a.step
2
>>>
21
ответ дан Python_Dude 16 August 2018 в 10:01
поделиться

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

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

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

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

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

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

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

возвращает True.

11
ответ дан Robert 16 August 2018 в 10:01
поделиться

Большинство приведенных выше ответов очищаются от нотации Slice. Расширенный синтаксис индексирования, используемый для нарезки, является aList[start:stop:step] базовыми примерами являются

:

Другие примеры нарезки: 15 Extended Slices

5
ответ дан Roshan 16 August 2018 в 10:01
поделиться
  • 1
    как насчет - & gt; A [:: - 1], как это понимать – kRazzy R 23 January 2018 в 21:10
  • 2
    Отрицательные значения также работают, чтобы сделать копию того же списка в обратном порядке. L = range(10) L[::-1] o / p: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] – Roshan 1 February 2018 в 19:08
  • 3
    – Ciro Santilli 新疆改造中心 六四事件 法轮功 4 September 2018 в 15:31
  • 4
    – Roshan Bagdiya 5 September 2018 в 07:27

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.

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

3
ответ дан SHASHI BHUSAN 16 August 2018 в 10:01
поделиться

Если вы чувствуете, что отрицательные индексы в нарезке сбивают с толку, вот очень простой способ подумать об этом: просто замените отрицательный индекс на 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 for-loop with start, end and step
  return [list[i] for i in range(start, end, step)]
3
ответ дан ShitalShah 16 August 2018 в 10:01
поделиться

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

(from:to:step)

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

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

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

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

47
ответ дан Simon 16 August 2018 в 10:01
поделиться

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

13
ответ дан Statham 16 August 2018 в 10:01
поделиться
  • 1
    Вы должны определить, какие модули / пакеты реализуют это. Вопрос был просто помечен python и list. – hpaulj 20 June 2017 в 00:36

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

mylist[X:Y]

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

31
ответ дан Steve Losh 16 August 2018 в 10:01
поделиться

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

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

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

200
ответ дан TomRoche 16 August 2018 в 10:01
поделиться

В 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]
84
ответ дан abc 16 August 2018 в 10:01
поделиться
  • 1
    еще один интересный пример: a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2], который приводит к [9] – Deviacium 10 July 2017 в 13:59
Другие вопросы по тегам:

Похожие вопросы: