인덱스가 범위를 벗어난 부분 문자열 슬라이싱이 작동하는 이유는 무엇입니까?


88

'example'[999:9999]오류가 발생 하지 않습니까? 이후 'example'[9]않는, 그 뒤에 동기는 무엇인가?

이 동작 에서 두 가지 모두 동일한 문자열을 생성하더라도 'example'[3]본질적으로 / 내부적으로.와 동일하지 않다고 가정 할 수 있습니다 .'example'[3:4]'m'


17
[999:9999]인덱스가 아니고 슬라이스이며 다른 의미를 가지고 있습니다. 파이썬 소개에서 : "슬라이스 인덱스 퇴화는 정상적으로 처리됩니다. 너무 큰 인덱스는 문자열 크기로 대체되고, 하한보다 작은 상한은 빈 문자열을 반환합니다."
Wooble

2
실제 대답입니다 @Wooble
jondavidjohn

2
@Wooble 그리고 왜 이런 식인지 아십니까? 설명해 주셔서 감사합니다.
ijverig

왜? 귀도에게 물어봐야 할 것이지만, 슬라이스가 항상 원래 시퀀스와 동일한 유형의 시퀀스라고 가정 할 수 있다는 것이 우아하다고 생각합니다.
Wooble

1
@Lapinot yes이 동작에 의존하는 코드를 작성했습니다. 불행히도 정확한 코드를 기억하지 못해서 이유를 말할 수 없습니다. 아마도 부분 문자열과 관련이있을 것입니다. 빈 문자열을 얻는 것은 때때로 원하는 것입니다.
Mark Ransom 2018

답변:


68

맞아요! 'example'[3:4]'example'[3]시퀀스의 경계 외부 근본적으로 다른, 그리고 슬라이스 있습니다 (내장 기능에 대한 최소한) 오류가 발생하지 않습니다.

처음에는 놀라 울 수도 있지만 생각해 보면 말이됩니다. 인덱싱은 단일 항목을 반환하지만 슬라이싱은 항목의 하위 시퀀스를 반환합니다. 따라서 존재하지 않는 값을 인덱싱하려고하면 반환 할 항목이 없습니다. 그러나 경계를 벗어난 시퀀스를 슬라이스하면 여전히 빈 시퀀스를 반환 할 수 있습니다.

여기서 혼란스러운 부분은 문자열이 목록과 약간 다르게 동작한다는 것입니다. 목록에 동일한 작업을 수행하면 어떻게되는지보세요.

>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]

여기서 차이점은 분명합니다. 문자열의 경우 결과는 동일한 것으로 보입니다. 파이썬에서는 문자열 외부에 개별 문자가 없기 때문입니다. 단일 문자는 1 자 문자열입니다.

(시퀀스 범위 밖에서 슬라이스하는 정확한 의미는 mgilson의 답변을 참조하십시오 .)


1
범위를 벗어난 인덱스는 오류가 발생하는 None대신 반환 될 수 있습니다. 이는 반환 할 것이 없을 때 일반적인 Python 규칙입니다.
Mark Ransom

8
@MarkRansom, 사실입니다. 그러나이 None경우 반환 하면 범위를 벗어난 인덱스와 None목록 내의 값 을 구분하기가 더 어려워집니다 . 그러나 이에 대한 해결 방법이 있더라도 경계를 벗어난 슬라이스가 주어 졌을 때 빈 시퀀스를 반환하는 것이 올바른 일이라는 것은 분명합니다. 두 개의 분리 된 집합을 결합하는 것과 유사합니다.
senderle 2012

분명히 말해서, 나는 당신이 틀렸다고 말하지 않았습니다. None목록의 값에 대한 귀하의 요점을 봅니다 .
Mark Ransom

1
@MarkRansom, 알아요-방어 적으로 들리면 죄송합니다. 정말로 나는 집합 이론을 참조하는 변명을 원했습니다. :).
senderle 2012

4
아, 내가 "교차"대신 "연합"이라고 말한 것 빼고.
senderle 2014

31

문서 의 강력한 섹션을 가리키는 답변을 추가하기 위해 :

같은 슬라이스 표현을 감안할 때 s[i:j:k],

k 단계 에서 i 에서 j 까지 의 s 조각 은 다음과 같은 인덱스가있는 항목의 시퀀스로 정의됩니다 . 즉, 인덱스는 , , , 때 등, 정지 j는 도달 할 때 (그러나 결코 포함되지 J ). 경우 K는 양수, IJ는 감소된다 가 크면x = i + n*k0 <= n < (j-i)/kii+ki+2*ki+3*klen(s)

당신이 쓰는 경우 s[999:9999], 파이썬은 반환 s[len(s):len(s)]이후 len(s) < 999와 단계는 긍정적 ( 1- 기본값).


아마도 때 k긍정적, ij도에 증가 -len(s)가 적은 경우? 예를 들면s = 'bac'; s[-100:2] == s[-len(s):2]
Chris_Rands

때 @Chris_Rands은 k긍정적이다, 파이썬은 확장 할 수 ij그래서 그들은 순서의 경계를 맞는 것이다. 귀하의 예에서는 s[-100:2] == s[0:2]( == s[-len(s):2], 그런데). 마찬가지로 s[-100:100] == s[0:2].
tylerc0816

좋아, 고마워. 이것은 위의 @speedplane의 의견에 대한 더 나은 응답입니다.
senderle dec

8

슬라이싱은 기본 제공 유형에 의해 경계가 확인되지 않습니다. 두 예제 모두 동일한 결과를 나타내는 것처럼 보이지만 작동 방식은 다릅니다. 대신 목록으로 시도하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.