슬라이스 표기법 이해


3282

파이썬의 슬라이스 표기법에 대한 좋은 설명 (참조는 플러스입니다)이 필요합니다.

나 에게이 표기법은 약간의 픽업이 필요합니다.

그것은 매우 강력 해 보이지만, 나는 그 주위에 내 머리를 갖지 못했습니다.

답변:


4500

정말 간단합니다.

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값 이 선택한 슬라이스에 없는 첫 번째 값을 나타냅니다 . 따라서, 차이 stopstart(만약 선택된 소자의 수는 step1, 기본값).

다른 특징이다 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

파이썬은 당신이 요구하는 것보다 적은 수의 아이템이 있다면 프로그래머에게 친절합니다. 당신이 요구하는 경우 예를 들어, a[:-2]그리고 a단 하나 개의 요소를 포함, 당신은 빈리스트 대신 오류가 발생합니다. 때로는 오류를 선호하기 때문에 이러한 상황이 발생할 수 있음을 알고 있어야합니다.

의 관계 slice()객체

슬라이싱 연산자 []는 실제로 위의 코드 slice()에서 :표기법 (에서만 사용됨)을 사용하는 객체 와 함께 사용 됩니다 [].

a[start:stop:step]

다음과 같습니다.

a[slice(start, stop, step)]

슬라이스 객체는 또한 인수 개수에 따라 약간 다르게 다르게 작동합니다 range(). 즉 둘 다 slice(stop)와 비슷하며 slice(start, stop[, step])지원됩니다. 주어진 인수의 지정을 건너 뛰려면을 사용할 수 있습니다 None. 예를 들어 a[start:]a[slice(start, None)]거나 a[::-1]같습니다 a[slice(None, None, -1)].

:기반 표기법은 간단한 슬라이싱에 매우 도움이 되지만, slice()객체를 명시 적으로 사용 하면 프로그래밍 방식으로 슬라이싱을 생성 할 수 있습니다.


122
내장 유형을 자르면 사본이 반환되지만 보편적이지 않습니다. 특히, NumPy 배열을 슬라이스 하면 원본과 메모리를 공유하는보기가 반환됩니다.
Beni Cherniavsky-Paskin

43
이것은 투표로 증명하는 아름다운 답변이지만 한 가지가 누락 None되었습니다. 빈 공간을 대체 할 수 있습니다. 예를 들어 [None:None]전체 사본을 만듭니다. 변수를 사용하여 범위의 끝을 지정해야하고 마지막 항목을 포함해야 할 때 유용합니다.
Mark Ransom

6
정말 짜증나는 것은 파이썬이 시작과 끝을 설정하지 않으면 기본값은 0이고 시퀀스 길이는 말합니다. 따라서 이론적으로 "abcdef"[::-1]을 사용할 때 "abcdef"[0 : 6 : -1]로 변환되어야하지만이 두 표현식은 동일한 출력을 얻지 못합니다. 언어를 만든 이후로 파이썬 문서에 뭔가 빠진 것 같습니다.
axell13 2016 년

6
그리고 "abcdef"[::-1]이 "abcdef"[6 : -7 : -1]로 변환되었으므로 가장 좋은 방법은 다음과 같습니다. len 은 시퀀스의 길이입니다. step이 양수 이면 start 및 end의 기본값은 0과 len 입니다. 단계가 음수 다른 경우 , 시작과 끝의 기본값은 있습니다 과 - - 1
axell13

4
stackoverflow.com/questions/39241529/… 는 이것의 속임수로 표시되어 있으므로 delwrt 슬라이스 표기법이 있는 섹션을 추가하는 것이 좋습니다. 특히, del arr[:]즉시 명확하지 않습니다 ( "arr [:] 사본을 만듭니다, 델도 그 사본을 삭제
합니까 ????

538

그만큼 파이썬 튜토리얼 그것에 대해 이야기 (약간 아래로 스크롤 당신은 슬라이스에 대한 부분에 도달 할 때까지).

ASCII 아트 다이어그램은 슬라이스의 작동 방식을 기억하는 데에도 도움이됩니다.

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

슬라이스의 작동 방식을 기억하는 한 가지 방법 은 첫 번째 문자의 왼쪽 가장자리가 0 인 인덱스를 문자 사이 를 가리키는 것으로 생각하는 것입니다. 그런 다음 n 개의 문자열 문자열의 마지막 문자의 오른쪽 가장자리 에는 인덱스 n이 있습니다.


10
이 제안은 긍정적 보폭에는 효과가 있지만 부정적인 보폭에는 효과가 없습니다. 그림에서, 나는 기대 a[-4,-6,-1]yP하지만입니다 ty. 항상 효과가있는 것은 문자 나 슬롯에서 생각하고 인덱싱을 반 열린 간격으로 사용하는 것입니다. 양의 보폭이면 오른쪽 열림, 음의 보폭이면 왼쪽 열림입니다.
aguadopd

그러나 처음부터 시작하여 빈 세트로 축소 할 수있는 방법이 없으므로 ( x[:0]처음부터 시작할 때 와 같이 ) 작은 배열을 특수해야합니다. : /
endolith

412

문법에 의해 허용되는 가능성을 열거 :

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

실제로 'apple'을 입력하면 'elp'가 표시됩니다. 파이썬은 -4를 1로 변환하고 있습니까?
liyuan

백틱은 더 이상 사용되지 않습니다.repr
wjandrea

@liyuan 형식 구현 __getitem__은 다음과 같습니다. 귀하의 예는와 동일합니다 apple[slice(4, -4, -1)].
chepner

320

위의 답변은 슬라이스 할당에 대해 설명하지 않습니다. 슬라이스 할당을 이해하려면 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']

하나의 휴리스틱은 0에서 n까지의 슬라이스에 대해 "0은 시작이며 처음부터 시작하여 목록에서 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']

또 다른 휴리스틱은 "어느 슬라이스 든 시작을 0으로 바꾸고 이전 휴리스틱을 적용하여 목록의 끝을 얻은 다음 첫 번째 숫자를 다시 계산하여 처음부터 항목을 잘라냅니다"입니다.

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

슬라이싱을 사용하면 완료되면 완료됩니다. 뒤로 자르기 시작하지 않습니다. 파이썬에서는 음수를 사용하여 명시 적으로 요청하지 않는 한 음수 보폭을 얻지 못합니다.

>>> p[5:3:-1]
 ['n','o']

"한 번 완료하면 완료"규칙에 이상한 결과가 있습니다.

>>> p[4:4]
 []
>>> p[5:4]
 []
>>> p[6:4]
 []
>>> p[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

사실, 인덱싱과 비교하여 파이썬 슬라이싱은 기이하게 오류를 방지합니다.

>>> p[100:200]
 []
>>> p[int(2e99):int(1e99)]
 []

때로는 유용 할 수 있지만 다소 이상한 동작이 발생할 수도 있습니다.

>>> p
 ['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
 ['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']

응용 프로그램에 따라, 당신이 원하는 것이거나 아닐 수도 있습니다!


아래는 원래 답변의 텍스트입니다. 많은 사람들에게 유용했기 때문에 삭제하고 싶지 않았습니다.

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

또한 슬라이싱과 인덱싱의 차이점을 명확히 할 수 있습니다.


246

파이썬의 슬라이스 표기법 설명

즉, 콜론 ( :첨자 표기법) ( subscriptable[subscriptarg]) 메이크업 슬라이스 표기법 - 옵션 인수가, start, stop, step:

sliceable[start:stop:step]

Python 슬라이싱은 계산적으로 데이터의 일부에 체계적으로 액세스하는 방법입니다. 제 생각에는 중급 파이썬 프로그래머가 되려면 익숙해야 할 언어의 한 측면입니다.

중요한 정의

우선 몇 가지 용어를 정의 해 보겠습니다.

start : 슬라이스의 시작 인덱스. stop 과 동일하지 않으면이 인덱스의 요소를 포함합니다 . 기본값은 0, 즉 첫 번째 인덱스입니다. 음수이면 n끝 부터 항목 을 시작한다는 의미 입니다.

중지 : 슬라이스의 끝 인덱스, 그렇지 않습니다 .이 인덱스에 요소를 포함 . 기본적으로 슬라이스되는 시퀀스의 길이, 즉 끝까지 포함합니다.

단계 : 인덱스가 증가하는 양의 기본값은 1입니다. 음수이면 iterable에 대해 반대로 자릅니다.

인덱싱 작동 방식

이 양수 또는 음수를 지정할 수 있습니다. 긍정적 인 숫자의 의미는 간단하지만 음수를 들어, 파이썬에서 인덱스처럼, 당신은의 끝에서 거꾸로 계산 시작정지 , 그리고위한 단계 , 당신은 단순히 인덱스를 감소. 이 예제는 문서의 튜토리얼에서 가져온 것이지만 각 인덱스가 참조하는 시퀀스의 항목을 나타내도록 약간 수정했습니다.

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

슬라이싱 작동 방식

슬라이스 표기법을 지원하는 시퀀스와 함께 슬라이스 표기법을 사용하려면 시퀀스 뒤에 오는 대괄호에 콜론을 하나 이상 포함해야합니다 ( 파이썬 데이터 모델에 따라 실제로 시퀀스 __getitem__방법을 구현 함) ).

슬라이스 표기법은 다음과 같이 작동합니다.

sequence[start:stop:step]

그리고 기본값이 있다는 것을 기억하십시오. 시작 , 정지단계 때문에, 기본값에 액세스 할 수 단순히 인수를 생략.

목록에서 마지막 9 개 요소 (또는 문자열과 같이이를 지원하는 다른 시퀀스)를 가져 오는 슬라이스 표기법은 다음과 같습니다.

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]

콜론 , :당신은 그것을 조각이 아닌 일반 인덱스를 제공하고 파이썬을 알 것입니다. 그렇기 때문에 파이썬 2에서 얕은 목록을 만드는 관용적 인 방법은

list_copy = sequence[:]

그리고 그것들을 지우는 것은 다음과 같습니다.

del my_list[:]

(파이썬 3는 list.copylist.clear 메소드를 .)

step부정적인, 기본값을위한입니다startstop 변경

기본적으로 step인수가 비어있는 경우 (또는None )+1 .

그러나 음수를 전달할 수 있으며 목록 (또는 대부분의 다른 표준 슬라 이블)은 처음부터 끝까지 슬라이스됩니다.

따라서 네거티브 슬라이스는 start및에 대한 기본값을 변경합니다stop !에 .

소스에서 이것을 확인

사용자가 문서뿐만 아니라 소스를 읽도록 권장합니다. 슬라이스에 대한 소스 코드는 객체와이 논리는 여기에서 발견된다 . 먼저 step부정적 인지 판단합니다 .

 step_is_negative = step_sign < 0;

그렇다면 하한은 -1 시작 부분을 포함하여 끝까지 슬라이스하고 상한은 길이에서 1을 뺀 값으로 끝에서 시작 함을 의미합니다. (참고 이것의 의미는 -1이다 상이한 A로부터 -1사용자가 마지막 항목을 나타내는 파이썬 인덱스를 통과 할 수있다.)

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

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

그렇지 않으면 step양수이고 하한은 0이되고 상한은 (우리가 포함하지만 포함하지 않는) 슬라이스 된 목록의 길이입니다.

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__메소드에 전달하는 것과 분리하는 것이 분리하는 것이 유용 할 수 있습니다 ( 대괄호가하는 일 ). 새로운 것이 아니더라도 코드를 더 읽기 쉽게 유지하여 코드를 읽어야하는 다른 사람들이 자신이하는 일을 더 쉽게 이해할 수 있도록합니다.

그러나 콜론으로 구분 된 정수를 변수에 지정할 수는 없습니다. 슬라이스 객체를 사용해야합니다.

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)

메모리 고려 사항 :

파이썬 목록 조각은 메모리에 새로운 객체를 생성하기 때문에 알아야 할 또 다른 중요한 기능은입니다 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과 같은 고급 개체를 슬라이스하는 경우 복사본이 아니라 원본에서보기를 반환 할 수 있습니다.


146

그리고 슬라이싱 구문을 처음봤을 때 나에게 분명하지 않은 몇 가지 사항이 있습니다.

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

100

파이썬 2.7에서

파이썬에서 슬라이싱

[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에서 끝납니다 (b 번째 인덱스의 요소 제외). 위의 색인 규칙을 사용하면이 범위의 요소 만 찾을 수 있습니다.

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

2
또 하나 흥미로운 예 : a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2]에 결과[9]
Deviacium

96

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)

65

그것을 조금 사용한 후에는 가장 간단한 설명이 for루프 의 인수와 정확히 동일하다는 것을 알고 있습니다 ...

(from:to:step)

그들 중 하나는 선택 사항입니다.

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

그런 다음 음수 인덱싱에서는 문자열 길이를 음수 인덱스에 추가하여 이해해야합니다.

이것은 어쨌든 나를 위해 작동합니다 ...


52

작동 방식을 기억하기가 더 쉽다는 것을 알게 된 후 특정 시작 / 중지 / 단계 조합을 알아낼 수 있습니다.

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 (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]전체 문자열입니다.


3
this_is_how_slicing_works파이썬 슬라이스와 동일하지 않습니다. EG [0, 1, 2][-5:3:3]는 파이썬에서 [0]을 list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3))얻지 만 [1]을 얻습니다.
Eastsun

@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):단순히 "시퀀스를 벗어나지 마십시오"를 구현하려고 시도했지만 1 단계>에서는 잘못되었습니다. 오늘 나중에 테스트를 통해 다시 작성하겠습니다.
Beni Cherniavsky-Paskin

40

나는 스스로 생각하는 "요소들 사이의 색인 포인트"방법을 사용하지만 때로는 다른 사람들이 이해하는 데 도움이되는 한 가지 방법은 다음과 같습니다.

mylist[X:Y]

X는 원하는 첫 번째 요소의 색인입니다.
Y는 원하지 않는 첫 번째 요소의 색인입니다 .


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

이것이 파이썬으로 목록을 모델링하는 데 도움이되기를 바랍니다.

참조 : http://wiki.python.org/moin/MovingToPythonFromOtherLanguages


38

파이썬 슬라이싱 표기법 :

a[start:end:step]
  • 내용 startend, 음의 값은 시퀀스의 끝을 기준으로 해석된다.
  • 양의 인덱스는 포함 할 마지막 요소 end 의 위치 를 나타냅니다 .
  • 공백 값은 기본적으로 다음과 같습니다 [+0:-0:1]..
  • 부정적 단계를 사용하면 해석이 반대로 start되고end

표기법은 (numpy) 행렬 및 다차원 배열로 확장됩니다. 예를 들어 전체 열을 슬라이스하려면 다음을 사용할 수 있습니다.

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

슬라이스는 배열 요소의 사본이 아닌 참조를 보유합니다. 배열을 별도로 복사하려면을 사용할 수 있습니다 deepcopy().


34

슬라이스 할당을 사용하여 목록에서 하나 이상의 요소를 제거 할 수도 있습니다.

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

33

이것은 약간의 추가 정보입니다 ... 아래 목록을 고려하십시오.

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

33

이것이 초보자에게 조각을 가르치는 방법입니다.

인덱싱과 슬라이싱의 차이점 이해 :

Wiki Python에는 인덱싱과 슬라이싱을 명확히 구분하는 놀라운 그림이 있습니다.

여기에 이미지 설명을 입력하십시오

6 개의 요소가 포함 된 목록입니다. 슬라이싱을 더 잘 이해하려면 해당 목록을 6 개의 상자 세트로 구성하십시오. 각 상자에는 알파벳이 있습니다.

인덱싱은 박스의 내용을 다루는 것과 같습니다. 모든 상자의 내용을 확인할 수 있습니다. 그러나 한 번에 여러 상자의 내용을 확인할 수 없습니다. 상자 내용물을 교체 할 수도 있습니다. 그러나 한 상자에 두 개의 공을 넣거나 한 번에 두 개의 공을 교체 할 수는 없습니다.

In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']

In [124]: alpha[0]
Out[124]: 'a'

In [127]: alpha[0] = 'A'

In [128]: alpha
Out[128]: ['A', 'b', 'c', 'd', 'e', 'f']

In [129]: alpha[0,1]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-129-c7eb16585371> in <module>()
----> 1 alpha[0,1]

TypeError: list indices must be integers, not tuple

슬라이스는 박스 자체를 다루는 것과 같습니다. 첫 번째 상자를 들고 다른 테이블에 놓을 수 있습니다. 상자를 집 으려면 상자의 시작과 끝 위치 만 알면됩니다.

처음 세 개의 상자 나 마지막 두 개의 상자 또는 1과 4 사이의 모든 상자를 선택할 수도 있습니다. 따라서 시작과 끝을 알고 있으면 모든 상자 세트를 선택할 수 있습니다. 이러한 위치를 시작 및 중지 위치라고합니다.

흥미로운 점은 한 번에 여러 개의 상자를 교체 할 수 있다는 것입니다. 또한 원하는 곳에 여러 상자를 배치 할 수 있습니다.

In [130]: alpha[0:1]
Out[130]: ['A']

In [131]: alpha[0:1] = 'a'

In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']

In [133]: alpha[0:2] = ['A', 'B']

In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']

In [135]: alpha[2:2] = ['x', 'xx']

In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']

단계를 가진 저 미기 :

지금까지 상자를 계속 골랐습니다. 그러나 때로는 신중하게 픽업해야합니다. 예를 들어, 매 초 상자를 선택할 수 있습니다. 끝에서 세 번째 상자를 모두 선택할 수도 있습니다. 이 값을 단계 크기라고합니다. 이는 연속 픽업 간의 간격을 나타냅니다. 상자를 처음부터 끝까지 선택하거나 그 반대의 경우 단계 크기는 양수 여야합니다.

In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']

In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']

In [144]: alpha[1:5:-2]
Out[144]: []

In [145]: alpha[-1:-5:2]
Out[145]: []

파이썬이 누락 된 매개 변수를 파악하는 방법 :

슬라이싱 할 때 매개 변수를 생략하면 Python은 자동으로 파악하려고 시도합니다.

CPython 의 소스 코드를 확인하면 PySlice_GetIndicesEx ()라는 함수를 사용하여 주어진 매개 변수에 대한 슬라이스 인덱스를 알아낼 수 있습니다. 다음은 파이썬에서 논리적으로 동등한 코드입니다.

이 함수는 슬라이싱을 위해 Python 객체와 선택적 매개 변수를 사용하여 요청 된 슬라이스의 시작, 중지, 단계 및 슬라이스 길이를 반환합니다.

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]

참고 : 이 게시물은 원래 내 블로그 인 The Python Behind Python Slices 에서 작성되었습니다 .


29

일반적으로 하드 코딩 된 인덱스 값이 많은 코드를 작성하면 가독성 및 유지 관리가 복잡해집니다. 예를 들어, 1 년 후 코드로 돌아 오면 코드를보고 코드를 작성할 때 무슨 생각을했는지 궁금해 할 것입니다. 표시된 솔루션은 코드에서 실제로 수행중인 작업을보다 명확하게 나타내는 방법입니다. 일반적으로 내장 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
>>>

25

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), 파이썬은 빈 조각을 반환합니다[] .

2. 함정

위의 부분은 슬라이스 작동 방식의 핵심 기능을 설명하며 대부분의 경우 작동합니다. 그러나 조심해야 할 함정이있을 수 있으며이 부분에서이를 설명합니다.

음의 인덱스

파이썬 학습자들을 혼란스럽게하는 첫 번째 것은 인덱스가 음수 일 수 있다는 것입니다 ! 당황하지 마십시오 : 음수 색인은 거꾸로 세는 것을 의미합니다.

예를 들면 다음과 같습니다.

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같지 않음 ). 예를 들면 다음과 같습니다.0s[::-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

24

이전 답변에서는 유명한 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쉼표 앞 의 " "은 1 차원에서 0:3:2작동하고 쉼표 뒤의 " "는 2 차원에서 작동합니다.


4
Python list에서는 이 작업을 수행 할 수 없지만 arrayNumpy 에서만 수행 할 수 있음을 알려주는 친절한 안내
Mars Lee

15
#!/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 씩 오른쪽으로 이동합니다.


14

내 두뇌 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.


12

내 의견으로는, 파이썬 문자열 슬라이싱 표기법을 다음과 같이 보면 더 잘 이해하고 기억할 것입니다.

다음 문자열로 작업 해 봅시다 ...

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 .

우리는 경계를 설정하고 있음을 기억하십시오. 그리고 그 경계는 다음과 같이 부분 문자열을 감싸는 괄호를 넣을 수있는 위치입니다 ...

ab [ cdefgh ] ij

그 트릭은 항상 작동하며 기억하기 쉽습니다.


11

이전 답변의 대부분은 슬라이스 표기법에 대한 질문을 해결합니다.

슬라이싱에 사용되는 확장 인덱싱 구문 aList[start:stop:step]은입니다. 기본 예는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오:

더 많은 슬라이스 예 : 15 개의 확장 슬라이스


10

파이썬에서 슬라이싱을위한 가장 기본적인 형태는 다음과 같습니다.

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]

처음부터 슬라이스 할 때는 0 인덱스를 생략하고 끝까지 슬라이스 할 때 중복되므로 최종 인덱스를 생략 할 수 있으므로 자세하게 설명하지 마십시오.

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파이썬에서 컬렉션을 뒤집는 유용한 트릭을 제공합니다.

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매우 혼란 스러울 수 있습니다. 또한, 일하기 위해 파이썬을 , 당신은 사용하지 말아야합니다 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]

10

안녕하세요, 월드를 하나 추가하고 싶습니다 ! 초보자를위한 슬라이스 기본 사항을 설명하는 예제입니다. 그것은 많은 도움이되었습니다.

6 개의 값을 가진 목록을 만들어 봅시다 ['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. 결과는 두 컷 사이의 슬라이스 인 list ['T', 'H', 'O']입니다.


10

나는 개인적으로 for루프 처럼 생각 합니다.

a[start:end:step]
# for(i = start; i < end; i += step)

또한, 마이너스 값 참고 start하고 end리스트의 끝을 기준으로하고 의해 위의 예에서 계산된다 given_index + a.shape[0].


8

아래는 문자열 색인의 예입니다.

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

str="Name string"

슬라이스 예 : [start : end : step]

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

아래는 사용법 예입니다.

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

5

슬라이싱에서 음수 인덱스가 혼동된다고 생각되면 여기에 대해 생각하는 매우 쉬운 방법이 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)]

4

기본 슬라이싱 기술은 시작점, 중지 점 및 단계 크기 (보폭이라고도 함)를 정의하는 것입니다.

먼저 슬라이싱에 사용할 값 목록을 만듭니다.

슬라이스 할 두 개의 목록을 작성하십시오. 첫 번째는 1에서 9까지의 숫자 목록입니다 (목록 A). 두 번째는 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)

A의 숫자 3과 B의 숫자 6을 인덱싱하십시오.

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

기본 슬라이싱

슬라이싱에 사용되는 확장 인덱싱 구문은 aList [start : stop : step]입니다. start 인수와 step 인수는 모두 none으로 기본 설정됩니다. 필요한 유일한 인수는 stop입니다. 이것이 범위가 목록 A와 B를 정의하는 데 사용 된 방법과 유사하다는 것을 알고 있습니까? 슬라이스 개체는 range (start, stop, step)에 의해 지정된 인덱스 집합을 나타 내기 때문입니다. 파이썬 3.4 문서.

보시다시피 stop 만 정의하면 하나의 요소 만 반환됩니다. 시작의 기본값은 none이므로 이는 하나의 요소 만 검색하는 것으로 해석됩니다.

첫 번째 요소는 인덱스 0이며 중요 하지는 않습니다. 인덱스 1이 인덱스 입니다. 이것이 우리가이 연습에 2 개의 목록을 사용하는 이유입니다. 목록 A의 요소는 서수 위치에 따라 번호가 매겨지며 (첫 번째 요소는 1, 두 번째 요소는 2 등) 목록 B의 요소는 색인을 만드는 데 사용되는 숫자입니다 (첫 번째 요소 0의 경우 [0], 기타.).

확장 된 인덱싱 구문을 사용하여 다양한 값을 검색합니다. 예를 들어, 모든 값은 콜론으로 검색됩니다.

A[:]

요소의 서브 세트를 검색하려면 시작 및 중지 위치를 정의해야합니다.

aList [start : stop] 패턴이 주어지면 List A에서 처음 두 요소를 검색하십시오.


3

나는 이 제안이 긍정적 보폭에는 효과가 있지만 부정적인 보폭에는 그렇지 않기 때문에 파이썬 튜토리얼 다이어그램 (다양한 다른 답변에 인용)이 좋다고 생각하지 않습니다.

이것은 다이어그램입니다 :

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

그림에서, 나는 기대 a[-4,-6,-1]yP하지만입니다 ty.

>>> a = "Python"
>>> a[2:4:1] # as expected
'th'
>>> a[-4:-6:-1] # off by 1
'ty'

항상 효과가있는 것은 문자 나 슬롯에서 생각하고 인덱싱을 반 열린 간격으로 사용하는 것입니다. 양의 보폭이면 오른쪽 열림, 음의 보폭이면 왼쪽 열림입니다.

이런 식으로, 나는 간격 용어 a[-4:-6:-1]로 생각할 수 있습니다 a(-6,-4].

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

 +---+---+---+---+---+---+---+---+---+---+---+---+
 | P | y | t | h | o | n | P | y | t | h | o | n |
 +---+---+---+---+---+---+---+---+---+---+---+---+
  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.