파이썬의 슬라이스 표기법에 대한 좋은 설명 (참조는 플러스입니다)이 필요합니다.
나 에게이 표기법은 약간의 픽업이 필요합니다.
그것은 매우 강력 해 보이지만, 나는 그 주위에 내 머리를 갖지 못했습니다.
답변
정말 간단합니다.
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
파이썬은 당신이 요구하는 것보다 적은 수의 아이템이 있다면 프로그래머에게 친절합니다. 당신이 요구하는 경우 예를 들어, 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()
객체를 명시 적으로 사용 하면 프로그래밍 방식으로 슬라이싱을 생성 할 수 있습니다.
답변
그만큼 파이썬 튜토리얼 그것에 대해 이야기 (약간 아래로 스크롤 당신은 슬라이스에 대한 부분에 도달 할 때까지).
ASCII 아트 다이어그램은 슬라이스의 작동 방식을 기억하는 데에도 도움이됩니다.
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
슬라이스의 작동 방식을 기억하는 한 가지 방법 은 첫 번째 문자의 왼쪽 가장자리가 0 인 인덱스를 문자 사이 를 가리키는 것으로 생각하는 것입니다. 그런 다음 n 개의 문자열 문자열의 마지막 문자의 오른쪽 가장자리 에는 인덱스 n이 있습니다.
답변
문법에 의해 허용되는 가능성을 열거 :
>>> seq[:] # [seq[0], seq[1], ..., seq[-1] ]
>>> seq[low:] # [seq[low], seq[low+1], ..., seq[-1] ]
>>> seq[:high] # [seq[0], seq[1], ..., seq[high-1]]
>>> seq[low:high] # [seq[low], seq[low+1], ..., seq[high-1]]
>>> seq[::stride] # [seq[0], seq[stride], ..., seq[-1] ]
>>> seq[low::stride] # [seq[low], seq[low+stride], ..., seq[-1] ]
>>> seq[:high:stride] # [seq[0], seq[stride], ..., seq[high-1]]
>>> seq[low:high:stride] # [seq[low], seq[low+stride], ..., seq[high-1]]
물론 만약 그렇다면 (high-low)%stride != 0
, 종말점은high-1
입니다.
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)'
답변
위의 답변은 슬라이스 할당에 대해 설명하지 않습니다. 슬라이스 할당을 이해하려면 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]
또한 슬라이싱과 인덱싱의 차이점을 명확히 할 수 있습니다.
답변
파이썬의 슬라이스 표기법 설명
즉, 콜론 ( :
첨자 표기법) ( 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.copy
및list.clear
메소드를 .)
때 step
부정적인, 기본값을위한입니다start
및stop
변경
기본적으로 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과 같은 고급 개체를 슬라이스하는 경우 복사본이 아니라 원본에서보기를 반환 할 수 있습니다.
답변
그리고 슬라이싱 구문을 처음봤을 때 나에게 분명하지 않은 몇 가지 사항이 있습니다.
>>> 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]
답변
파이썬 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]