슬라이스 표기법을 사용하여 목록 반전


80

다음 예에서 :

foo = ['red', 'white', 'blue', 1, 2, 3]

여기서 : foo[0:6:1]foo의 모든 요소를 ​​인쇄합니다. 그러나 foo[6:0:-1]첫 번째 또는 0 번째 요소는 생략됩니다.

>>> foo[6:0:-1]
[3, 2, 1, 'blue', 'white']

foo.reverse () 또는 foo [::-1]을 사용하여 목록을 반대로 인쇄 할 수 있다는 것을 이해하지만 foo [6 : 0 : -1]이 전체 목록을 인쇄하지 않는 이유를 이해하려고합니다. ?


3
foo[7:None:-1]가능성 도 참고하십시오 :)
tzot

1
슬라이스 표기법을 이해하기 전에 파이썬을 사용한 적이 없습니다. 제 질문은 왜 foo [6 : 0 : -1]이 인덱스 오류에서 벗어나지 않는지입니다. 파이썬은 그것에 대해 신경 쓰지 않습니까? 위의 예제 배열에서는 6 인덱스를 사용할 수 없기 때문입니다.
Mubashar

3
@MubasharAhmad Slicing은 인덱싱이 아니며 경계를 넘어갈 때 오류가 발생하지 않습니다. 그러나 인덱싱은 범위를 벗어날 때 예외를 발생시킵니다.
huggie 2014-04-13

답변:


152

간단히 슬라이스 표기법 :

[ <first element to include> : <first element to exclude> : <step> ]

목록을 뒤집을 때 첫 번째 요소를 포함하려면 다음과 같이 중간 요소를 비워 둡니다.

foo[::-1]

일반적으로 Python 슬라이스에 대한 몇 가지 좋은 정보를 찾을 수 있습니다.
Python의 슬라이스 표기법 설명


42
이것은 [ <first element to include> : <first element to exclude> : <step> ]내가 본 슬라이스 구문에 대한 가장 명확한 설명입니다. 이를 "제외 할 첫 번째 요소"라고 부르면 무슨 일이 일어나고 있는지 분명하게 알 수 있습니다.
Schof

네거티브 단계가있는 네거티브 슬라이스는 어떻습니까? 나는 아직도 그것을 이해하지 못한다.
huggie 2014-04-13

6
음수 인덱스를 사용 <first element to include>하거나 <first element to exclude>목록 뒤에서 인덱싱하는 경우 -1마지막 요소도 마찬가지 이고 -2두 번째에서 마지막 요소까지 등입니다. 따라서 예를 들어 x[-1:-4:-1]의 마지막 세 요소를 x역순으로 가져옵니다 . 따라서이를 "뒤로 이동 -1하면 목록의 마지막 요소 ( -1 <first element to include>)에서 끝 ( -4 <first element to include>) 에서 네 번째 요소를 포함하지 않을 때까지 각 요소 ( 단계)를 가져옵니다 "라고 해석 할 수 있습니다 .
Andrew Clark

1
후진 할 때 (즉, <step>이 경우 -1) 생각하는 데 도움이됩니다 <first element to include, moving from right to left>. 따라서 n목록에서 "가장 왼쪽"요소를 역순 으로 가져 오려면 : foo[n-1::-1]. n"가장 오른쪽"요소를 역순으로 가져 오려면 : foo[-1:-n-1:-1].
djvg

1
"앞의 요소"를 제외하는 첫 번째 요소를 어떻게 만드 foo[0]나요?
BallpointBen

9

슬라이스 표기법을 기억하는 데 문제가있는 경우 Hokey Cokey를 시도해 볼 수 있습니다 .

[ In : Out : 흔들어주세요 ]

[먼저 소자 에서 첫째 소자 떠날 clude 아웃 다음 단계 를 사용하는]

YMMV


7

... foo [6 : 0 : -1]이 전체 목록을 인쇄하지 않는 이유는 무엇입니까?

중간 값은 포함이 아닌 독점 중지 값이기 때문입니다. 간격 표기 [기동, 정지)된다.

이것이 바로 [x] range의 작동 방식입니다.

>>> range(6, 0, -1)
[6, 5, 4, 3, 2, 1]

그것들은 결과 목록에 포함되는 인덱스이며 첫 번째 항목에는 0이 포함되지 않습니다.

>>> range(6, -1, -1)
[6, 5, 4, 3, 2, 1, 0]

그것을 보는 또 다른 방법은 다음과 같습니다.

>>> L = ['red', 'white', 'blue', 1, 2, 3]
>>> L[0:6:1]
['red', 'white', 'blue', 1, 2, 3]
>>> len(L)
6
>>> L[5]
3
>>> L[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

인덱스 6은 L에 대한 유효한 인덱스를 넘어서 (정확히 한 과거), 범위에서 제외 된 중지 값으로 제외됩니다.

>>> range(0, 6, 1)
[0, 1, 2, 3, 4, 5]

여전히 목록의 각 항목에 대한 색인을 제공합니다.


1
range할 수 있지만 슬라이스는 할 수 없습니다 -1. 왜냐하면 마지막 요소 이기 때문 입니다. 그래서 l=[1, 2, 3], l[2:-1:-1] == [].
Simin Jie

6

이 답변은 약간 구식 일 수 있지만 같은 문제를 겪고있는 사람에게는 도움이 될 수 있습니다. 다음과 같이 두 번째 내부 슬라이스를 적용하여 인덱스가 0 인 임의의 끝을 가진 역방향 목록을 얻을 수 있습니다.

>>> L = list(range(10))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (start_ex, end) = (7, 0)
>>> L[end:start_ex][::-1]
[6, 5, 4, 3, 2, 1, 0]

1
모든 경우에 동일한 구문을 사용할 수 있기 때문에 이것은 실제로 매우 유용합니다. 0을 특별한 경우로 취급 할 필요가 없습니다.
Tom Zych

이것은 네거티브 슬라이싱에 대한 Python / numpy의 기본 동작보다 더 합리적입니다. 일반적으로 이미지 또는 텐서를 주어진 가장자리에 정렬 된 이미지 또는 텐서를 슬라이스 및 / 또는 반전시키고 싶어하는 반면 Python / numpy는 데이터 o_O의 마지막 행 / 열을 잃기 때문입니다.
Dwayne Robinson


1

음수 중지 값을 사용하면 작동하도록 할 수 있습니다. 이 시도:

foo[-1:-7:-1]

0

보어. 2 단계를 반대로하려면

A = [1,2,2,3,3]
n = len(A)
res = [None] * n
mid = n//2 + 1 if n%2 == 1 else n//2

res[0::2] = A[0:mid][::-1]
res[1::2] = A[0:mid][::-1]
print(res)

[2, 3, 2, 3, 1]


0

andrew-clark 의 답변을 조금 더 공식화합니다 .

목록 vv[n1:n2:n3]슬라이스를 가정합니다 . n1초기 위치, n2최종 위치 및 n3단계

Python 방식으로 pseucode를 작성해 보겠습니다.

n3 = 1  if (n3 is missing) else n3
if n3==0:
   raise exception # error, undefined step

첫 번째 부분 : n3 양성

if n3>0:
   slice direction is from left to right, the most common direction         

   n1 is left slice position in `v` 
   if n1 is missing: 
      n1 = 0   # initial position
   if n1>=0:
      n1 is a normal position
   else: 
     (-n1-1) is the position in the list from right to left 

   n2 is right slice position in `v` 
   if n2 is missing: 
      n2 = len(x)  # after final position
   if n2>=0:
      n2 is a normal final position (exclusive)
   else: 
      -n2-1 é the final position in the list from right to left 
       (exclusive)

두 번째 부분 : n3 네거티브

else: 
  slice direction is from right to left (inverse direction)

  n1 is right slice position in `v` 
  if n1 is missing: 
     n1 = -1   # final position is last position in the list.
  if n1>=0:
     n1 is a normal position
  else: 
     (-n1-1) is the position in the list from right to left 

  n2 is  left slice position in `v` 
  if n2 is missing: 
     n2 = -len(x)-1   # before 1st character  (exclusive)
  if n2>=0:
     n2 is a normal final position (exclusive)
  else: 
     -n2-1 is the ending position in the list from right to left 
     (exclusive)

이제 원래 문제 a : 슬라이스 표기법으로 목록을 뒤집는 방법?

L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(L(::-1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

왜?
n1 is missing and n3<0 => n1=0
n2 is missing and n3<0 => n2 = -len(x)-1

그래서 L(::-1) == L(-1:-11:-1)

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