Colon in Python

이번시간에는 파이썬 배열의 :를 활용하는 방법에 대해 공부해볼게요.

배열에서의 콜론

# 5개의 정수가 들어있는 배열을 하나 선언합니다
>>> example = [1, 2, 3, 4, 5]

# 2번째 인덱스 오른쪽의 모든 아이템을 가져와라
>>> example[2:]
[3, 4, 5]

# 2번째 인덱스 왼쪽의 모든 아이템을 가져와라
>>> example[:2]
[1, 2]

# 2부터 4까지의 아이템을 가져와라
>>> example[2:4]
[3, 4]

# 2부터 4까지 아이템 바꿔치기
>>> example[2:4] = [10, 11]
>>> example
[1, 2, 10, 11, 5]

이차원 배열에서는 다음과 같이 활용할수 있습니다. 우선 numpy라이브러리를 사용하기 위해서 현재 python버젼에 numpy를 설치해줄게요.

> pip install numpy
# numpy를 사용하기 위해서 라이브러리를 추가하고
>>> import numpy as np

# 0부터 39까지 아이템을 가진 배열을 하나 만듭니다.
>>> arr2d = np.arange(0,40)
>>> arr2d
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39])

# 해당 배열을 5개행, 8개열로 나눠서 이차원 배열로 만듭니다. 
>>> arr2d = arr2d.reshape([5, 8])
>>> arr2d
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29, 30, 31],
       [32, 33, 34, 35, 36, 37, 38, 39]])

# 첫번째 행의 모든 원소를 가져와라
>>> arr2d[0, :]
array([0, 1, 2, 3, 4, 5, 6, 7])

# 첫번째 열의 모든 원소를 가져와라
>>> arr2d[: ,0]
array([ 0,  8, 16, 24, 32])

위의 예제에서 보시는 바와 같이 배열에서 :는 모든 원소를 의미하며, 앞이나 뒤에 숫자가 붙으면 반환할 원소들의 시작 주소로 인식하게 됩니다.

문자열에서 콜론

문자열에서 :은 문자열을 쪼개는데 사용됩니다.

>>> a = "AskPython"
>>> print(a[2:8])
kPytho

>>> a = "AskPython"
>>> print(a[3:])
Python

>>> a = "AskPython"
>>> print(a[:7])
AskPyth

>>> a = "AskPython"
>>> print(a[-5:-2])
yth

Double Colon ::

더블콜론은 콜론과 마찬가지로 문자열이나 배열을 쪼갤때 사용되는데 추가로 아이템들을 건너뛰면서 쪼갤수 있습니다.

>>> string = "Ask Python"[5::]
>>> print(string)
ython

>>> string = "What's up AskPython"[0:19:2]
>>> print(string)
Wa' pAkyhn

>>> string="What's up AskPython"[::2]
>>> print(string)
Wa' pAkyhn

위의 예시에서 보는 바와같이 더블콜론은 [Start : Stop : Steps]의 형식을 가집니다.

Colon in Assignment Expressions

The Walrus :=

할당기호(:=)가 바다코끼리를 닮았다고 해서 바다코끼리라고도 불리우는 이 operator는 계산도중 값을 저장하고 싶을때 주로 사용됩니다. 예를 들면 아래의 코드처럼 numbers라는 배열을 돌면서 해당 값이 slow함수를 거쳤을때 0보다 큰 경우 slow함수의 결과를 반환하도록 합니다.

numbers = [7, 6, 1, 4, 1, 8, 0, 6]
results = [slow(num) for num in numbers if slow(num) > 0]

이때, 반환시에 slow함수를 한번더 호출하는 것보다 조건을 비교할때 value라는 변수에 저장을 해두었다가 해당 변수를 반환하면 slow함수를 두번 호출하는 번거로움을 줄일수 있어서 더 효율적입니다.

results = [value for num in numbers if (value := slow(num)) > 0]

물론 위의 코드를 옛날방식으로 바꿔서 for문에 넣고 기존 할당기능를 이용해서 아래와 같이 구현할수도 있습니다.

results = []
for num in numbers:
    value = slow(num)
    if value > 0:
        results.append(value)

하지만 이 방법은 코드를 읽어야만 기존리스트를 이용해서 새로운 리스트를 만든다는 것을 알수 있는 반면, 위의 코드는 간결하게 한눈에 기존 리스트를 변환하여 새로운 리스트를 만든다는 그 의도를 한눈에 파악할수 있습니다.

BNF (Backus–Naur Form) notation ::=

가끔 파이썬 코드를 보다보면 ::=를 사용한 예제가 있습니다. ::=:=와 같은 기능을 하지만 :=는 파이썬의 문법인 반면, ::=는 BNF라는 표기법의 형식입니다. BNF는 언어에 관계없이 널리 사용되고 있는 표기법이며, 이 표기법을 파이썬에서도 지원하고 있습니다. 이렇게 언어에 관계없이 사용되어지는 문법표현들을 모아서 metasyntax라고 부릅니다.