최근 수정 시각 : 2024-04-13 18:22:23

Python/문법

파일:상위 문서 아이콘.svg   상위 문서: Python
프로그래밍 언어 문법
{{{#!wiki style="margin: -16px -11px; word-break: keep-all"<colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 C(포인터) · C++(자료형 · 특성 · 클래스 · 이름공간 · 상수 표현식) · C# · Java · Python · Kotlin · MATLAB · SQL · PHP · JavaScript
마크업 문법 HTML · CSS
개념과 용어 함수 · 인라인 함수 · 고차 함수 · 람다식 · 리터럴 · size_t · 상속 · 예외 · 조건문 · 참조에 의한 호출 · eval
기타 == · === · NaN · null · undefined · 모나드 · 배커스-나우르 표기법
프로그래밍 언어 예제 · 목록 · 분류 }}}

1. 개요
1.1. 코딩 스타일
2. 자료형
2.1. 숫자(Number)2.2. 리스트(List), 튜플(Tuple)2.3. 문자열(String)2.4. 딕셔너리(Dictionary)2.5. 부울(bool)
2.5.1. Truthy/Falsy
2.6. Data Type(자료형 변환)
3. 입출력4. 들여쓰기5. 조건문
5.1. 2항 연산자5.2. 3항 연산자
6. 반복문
6.1. for 문6.2. while 문
7. 함수
7.1. 일반 함수7.2. 람다 함수
7.2.1. 응용
8. 슬라이싱
8.1. map
9. 예외 처리10. 팁

1. 개요

Python의 문법을 설명한다. 기준은 3.x.x대이다.

1.1. 코딩 스타일

여러 사람들이 같이 프로젝트를 할 때는, 통일된 방식으로 문서를 짜는 게 가독성과 유지 보수 면에서 편리하다.

가장 유명한 방식은 Python의 창시자 '귀도 반 로섬'이 제시한 코딩 스타일인 PEP-8 이다. PEP-8 코딩 스타일 한국어 번역판

2. 자료형

C, Java와 달리 파이썬은 변수를 선언할 때 따로 자료형을 지정하지 않는다. 내부적으론 자료형이 있으나 런타임에서 인터프리터가 추론한다.[1]

파이썬은 객체 지향 언어이고 원시 자료형이 없기 때문에 모든 값은 반드시 객체로 간주된다. 따라서 모든 데이터의 자료형은 그 데이터의 클래스이다. type() 함수로 변수의 자료형을 확인할 수 있다.

<예시>
#!syntax python
class Value:
    pass

var = Value()
print(type(var)) # <class '__main__.Value'>

2.1. 숫자(Number)

정수(int)는 길이 제한이 없어 큰 수도 별도의 자료형을 지정하지 않고 작은 수와 똑같이 다룰 수 있는 편리함을 지닌다. 실수는 8바이트로 제한된다.
#!syntax python
a = 1234 # 정수형
b = 3.14 # 실수형
print(type(a), type(b)) # <class 'int'> <class 'float'>

2.2. 리스트(List), 튜플(Tuple)

파이썬의 리스트는 말 그대로 순서대로 저장하는 시퀀스이자 변경 가능한 목록(Mutable List)을 말한다. 입력 순서가 유지되며, 내부적으로는 동적 배열로 구현되어 있다.
파일:3-7-2.png
타 언어의 배열처럼 파이썬도 array라는 배열에 해당하는 모듈을 제공하긴 하지만 기본적인 기능만을 제공하며, 사실상 리스트가 배열의 역할을 대체한다. 파이썬의 리스트는 다른 언어에서 제공하지 않는 매우 다양하고 편리한 기능을 제공한다. 리스트를 사용하면 사실상 스택(자료구조)을 사용할지 큐(자료구조)를 사용할지를 고민하지 않아도 되며, 스택과 큐에서 사용 가능한 모든 연산을 동시에 제공한다. 리스트는 객체로 되어 있는 모든 자료형을 다음 그림과 같이 포인터로 연결하는 구조로 되어 있다.
파일:2-5-2.png
파이썬은 모든 것이 객체며, 파이썬의 리스트는 이들 객체에 대한 포인터 목록을 관리하는 형태로 구현되어 있다. 사실상 연결 리스트에 대한 포인터 목록을 배열 형태로 관리하고 있으며, 그 덕분에 파이썬의 리스트는 배열과 연결리스트를 모두 합친 듯이 강력한 기능과 문법을 제공한다.

리스트는 객체가 수정 가능하지만, 튜플은 최초 생성 이후 수정이 불가능하다. list()tuple() 함수를 통해 서로 형 변환이 가능하다. 고차원 리스트도 가능하다.
<예시>
#!syntax python
l = [1, 2, 3] #일차원 리스트
t = tuple(l) #튜플로 변환
li = list(t) #리스트로 변환
l = [[1, 2, 3], [1, 2, 3]] #이차원 리스트

리스트와 튜플의 값을 참조할 때에는 변수명[숫자]의 형태로 입력한다. 아래는 각각 일차원 리스트, 이차원 리스트, 튜플의 값을 출력하는 코드이다.
#!syntax python
li_one = [1, 2, 3] # 일차원 리스트
li_two = [[1, 2, 3], [4, 5, 6]] # 이차원 리스트
tu = (7, 8) # 튜플

print(li_one[0], li_two[0][1], tu[1]) # 1 2 8

이때, #!syntax python print(li_one[0], li_two[0][1], tu[1]) 부분을 #!syntax python print(li_one[3], li_two[2][1], tu[2])와 같이 작성하면 리스트, 튜플에 없는 원소를 참조하기 때문에 오류가 발생한다.
Traceback (most recent call last):
  File "[파일명]", line 1, in <module>
IndexError: list index out of range

2.3. 문자열(String)

글자로 이루어진 변수를 스트링 변수라고 한다. 따옴표를 이용하여 표기한다.
<예시>
#!syntax python
>>> a = 'text'

따옴표를 이용하지 않으면 오류가 걸린다.
#!syntax python
>>> a = text

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'text' is not defined

text라는 변수가 정의되었으면 오류가 안걸린다.
사용할 수 있는 따옴표로는 작은 따옴표('), 큰 따옴표("), 작은 따옴표 3개('''), 큰 따옴표 3개(""")가 있다. 스트링 안에 따옴표 문자가 들어갈 때 사용한다.
<예시>
#!syntax python
a = " ' 를 포함한 문장"
b = ''' " 을 포함한 문장'''

2.4. 딕셔너리(Dictionary)

파이썬의 딕셔너리는 키/값 구조로 이뤄진 딕셔너리를 말한다. 파이썬 3.7 이상에서는 입력 순서 또한 유지되며, 내부적으로는 해시 테이블(Hash Table)로 구현되어 있다. 3.6 이하에서는 입력 순서를 보장하지 않으므로 유의해야 한다. 중괄호를 사용해서 선언한다.
#!syntax python
a = {}

다음과 같이 key1, key2는 초깃값으로 지정해 선언하거나 key3처럼 나중에 별도로 선언하여 value3라는 값을 할당할 수 있다.
#!syntax python
>>> a = {'key1':'value1', 'key2':'value2'} 
>>> a
{'key1': 'value1', 'key2': 'value2'}
>>> a['key3'] = 'value3'
>>> a
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

키에는 해시가능한(hashable) 자료형만 가능하며, 값에는 리스트 뿐만 아니라 집합 자료형 등 모든 자료형이 가능하다.
#!syntax python
>>> a = {'key1':[1, 2, 3], 'key2': (4, 5, 6)}
>>> a
{'key1': [1, 2, 3], 'key2': (4, 5, 6)}

2.5. 부울(bool)

bool이란 참(True)과 거짓(False)으로만 이루어진 자료형이다. 대문자를 쓴다는 점이 다른 프로그래밍 언어와 독특하게 구분된다. 소문자로 쓰면 예약어로서 기능하지 않는다.

#!syntax python
>>> a == 1

이라고 입력하면 a가 1이라면 'True', 그 외의 것이라면 'False'가 출력된다.
참, 거짓도 변수로 만들 수 있다.

#!syntax python c = True
if x > 10:
    c = False 

이런 식으로 직접 True or False 값을 할당시켜 쓸 수 있다.
#!syntax python
while True:
    print('hello')

라고 하면 hello를 계속 출력하는 것처럼 무한 루프를 만들 수도 있다.

주의할 점은 무조건 True/False로만 입력해야 한다는 것이다. 대소문자가 달라져 버리면[2] 예외가 발생한다.
#!syntax python
>>> isntTrue = true # 에러 발생.

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined.

2.5.1. Truthy/Falsy

일부 언어와 마찬가지로, 파이썬도 특정 값이나 객체에 참 또는 거짓의 논리를 부여할 수 있다. 이는 논리 연산을 할 때 매우 유용하게 사용할 수 있다.

예를 들어 문자열이 유효한지 검사할 때
#!syntax python
string = ''
if len(string) > 0: ~

이렇게 해야 할 것을
#!syntax python
string = ''
if string: ~

와 같이 손쉽게 처리할 수 있다.

파이썬에서 기본적으로 특정 논리를 갖는 값은 다음과 같다.
  • Truthy: True, 0이 아닌 수, 유효한 문자열(비지 않은 문자열), 유효한 리스트, 유효한 튜플
  • Falsy: False, None, 0, 빈 문자열, 빈 리스트, 빈 튜플 등

그 외에도 자체적으로 선언한 객체에 bool 논리를 부여해 주려면 __bool__ 메소드를 사용하면 된다. __bool__ 메소드가 없는데 __len__ 메소드가 있다면 해당 메소드에 따라 길이가 0이면 False, 0보다 크면 True로 간주하고, __bool__, __len__ 둘 다 없으면 무조건 True로 취급한다.

#!syntax python
class Value:
    def __init__(self):
        self.valid = False
    def __bool__(self):
        return self.valid
    def setValidity(self, validity):
        self.valid = validity

var = Value()
print(bool(var))  # False
var.setValidity(True)
print(bool(var))  # True

class Stack:
    def __init__(self):
        self.stack = list()
    def __len__(self):
        return len(self.stack)
    def push(self, x):
        self.stack.append(x)
    def pop(self):
        return self.stack.pop()

stack = Stack()
print(len(stack))   # 0
print(bool(stack))  # False

stack.push(100)     # 100 입력
print(len(stack))   # 1
print(bool(stack))  # True

stack.pop()         # 100 출력
print(len(stack))   # 0
print(bool(stack))  # False

2.6. Data Type(자료형 변환)

자료형(바꿀 변수)의 형태로 아주 간단하게 변경 가능하다.
  • str() - float형이나 int형을 문자열로 변환할 때 사용한다. 제일 기본적으로 쓰인다.
  • int() - 정수형으로 바꾼다. 양의 실수와 음의 실수 모두 소수점을 버린다.
  • float() - 실수형으로 바꾼다.
  • complex() - 복소수형으로 바꾼다. 허수는 i가 아니라 j로 표기한다.
  • list() - 리스트로 바꾼다. tuple과 형변환에 자주 사용된다.
  • tuple() - 튜플로 바꾼다. list와의 형변환에 자주 사용된다.
  • set() - 세트형(집합형)으로 바꾼다. 리스트나 튜플은 중복 원소를 허용하지만 세트는 중복을 허용하지 않으므로, 임의의 리스트나 튜플을 세트형으로 변환시키면 중복이 자동으로 제거되는 유용함을 지닌다.

앞서 언급했듯 파이썬의 모든 자료형은 '클래스'이므로 사용자 정의 클래스 자료형으로 바꿀 때도 똑같은 방법으로 하면 된다.

3. 입출력

기본적으로 출력은 print() 함수를 사용한다. 따로 줄바꿈을 추가하지 않아도 자동으로 줄바꿈까지 출력한다.
#!syntax python
# Hello, world! 문자열 출력 
print("Hello, world!")

변수를 출력하는 방법은 여러가지가 있다.
#!syntax python
a = 10
b = 20

# 10 , 20 출력
# 1. 인자 여러개로 주기
print(a, "," , b)

# 2. c 스타일 
print("%d , %d" % (a,b))

c 스타일에다가 %f를 쓰면 float 형을 출력 할 수 있고, %f.2를 넣으면 소수점 아래 2자리까지 출력된다. 2는 다른 숫자로 대체 가능하다.

#!syntax python
# 3. format 함수
print("{} , {}".format(a, b))

# 4. f-string
print(f"{a} , {b}")

print()에 인자를 여러개 준 경우 각각의 문자열이 한 칸 공백을 두고 출력된다.

끝의 문자에 줄바꿈이 아닌 다른 문자열이 포함되게 할 수 있다.
#!syntax python
print("a", end="") #공백 없음
print("b")

이런 식으로 입력하면 ab 식으로 연달아서 출력된다.

그리고 print에 여러 문자열을 넣고, 그 사이에 다른 문자열이 포함되도록 할 수 있다.
#!syntax python
print("하", "하", "하", sep = ".")

이러면 하.하.하 식으로 출력된다.

입력은 input()을 사용한다.
input()은 기본적으로 str 형태로 값을 받으며, 특정 자료형 함수를 이용하면 다른 형으로 값을 받을 수 있다. 그 자료형으로 값이 입력되지 않는다면,[3] 예외 오류가 일어난다.
#!syntax python
a = input("---->")
b = int(input("---->"))
c = float(input("---->"))

이렇게 쓰면 출력창에 ---->라는 메시지가 나타나며, 커서가 그곳으로 이동되어 입력을 할 수 있다. 그러면 각각 a, b, c 변수에 그 값이 저장된다.

입력에서 걸리는 시간을 줄이려면 sys 모듈의 stdin.readline()을 이용하면 좋다. 다만, 이 경우는 input()과는 달리 입력받는 기능만을 할 수 있다.
#!syntax python
import sys
a = sys.stdin.readline()
b = int(sys.stdin.readline())
c = float(sys.stdin.readline())

4. 들여쓰기

Python 특유의 디자인 철학에 따라 Python은 분기문과 반복문 등을 사용할 때 들여쓰기를 행해야 한다. 보통 권장되는 것은 4번 띄어쓰기이지만, Python 자체에서 자동 들여쓰기의 칸수를 결정할 수 있고 Tab은 권장되지 않으나 일부 텍스트 에디터에서 Tab의 스페이스 개수를 설정할 수 있기 때문에 큰 문제는 아니다. 2번이든 4번이든 한번 했으면 그걸로 계속 써야 한다. 그렇지 않으면 예외 오류가 일어난다.
<예시>
#!syntax python
if True:
    print("Hello world")  #4칸 들여쓰기
for n in range(0, 10):
  print(n) #2칸 들여쓰기
#문법 오류

5. 조건문

python의 조건문에서는 if, else 그리고 else if를 축약한 elif가 쓰인다. 예를 들어 부호 함수는 다음과 같이 쓸 수 있다.
#!syntax python
n = int(input("숫자를 입력하세요 ---->"))
if n > 0:
    print(f"{n}은 양수 입니다.")
elif n < 0:
    print(f"{n}은 음수입니다.")
else:
    print(f"{n}은 0입니다.")

사실 이 경우는 다음과 같이 써도 제대로 동작한다.
#!syntax python
n = int(input("숫자를 입력하세요 ---->"))
if n > 0:
    print(f"{n}은 양수 입니다.")
if n < 0:
    print(f"{n}은 음수입니다.")
if n == 0:
    print(f"{n}은 0입니다.")

다만 위와의 차이점은, elif는 위의 조건이 맞지 않고 해당 조건과 일치 할 시 출력하는 것이고, if는 조건만 맞으면 출력하는 거다. 이러한 상황에는 모두 if로 써도 상관이 없지만, 상황에 따라 오류가 날 수 있다.

다음은 변수 x의 대소 관계를 비교하는 코드이다.
#!syntax python
a = 120
if a < 100:
    print(1)
elif a < 50:
    print(2)
else:
    print(3)


이러한 상황에서 elif를 if로 바꾼다면, 1과 2가 모두 출력될 것이다. 왜냐면 120은 100보다도 크고 50보다도 크기 때문이다. 이러한 상황에 elif를 쓰는 것이다.

5.1. 2항 연산자

2항 연산자는 참의 논리(Truthy)를 갖는 값을 갖는다. ||와 &&가 아니라 or과 and가 쓰인다.

#!syntax python
x or y

<예시>
#!syntax python
var = 'Hello' or []
print(var) 
#결과는 'Hello'

#!syntax python
if True and False:
    print("true!")
else:
    print("false!")
#결과는 'false!'

5.2. 3항 연산자

3항 연산자는 참인 경우와 거짓인 경우 다른 값을 갖는 것으로,
#!syntax python
x if T else y

는 T가 True 일때 x, False일 때 y의 값을 갖는다.
<예시>
#!syntax python
def sgn(x):
    return 1 if x > 0 else (0 if x == 0 else -1)

이 코드는 부호 함수를 구현한다.

6. 반복문

Python에서는 다음과 같이 반복문을 작성한다.

6.1. for 문

#!syntax python
for x in X:
    todo

# 혹은

for i in range(start, stop[, step]):
    todo

위 코드는 배열 또는 range 형태인 X의 각 원소 x에 대해서 todo를 실행한다.

<예시>
#!syntax python
for i in range(10):
    print(i)

위 코드는 0부터 9까지의 정수를 한 줄에 하나씩 출력한다. range는 0부터 n-1까지의 값을 담는 코드[4]인데, i에 range의 값을 하나씩 넣으며 반복한다는 코드이다. 이러면 총 10번 반복되게 된다.

기본적으로 한 개의 매개변수를 전달할 때는 start의 기본값은 0, step의 기본값은 1로 설정되며, 0부터 (전달값 - 1)까지의 수를 하나씩 가져와 i에 저장한다.

<예시 1>
#!syntax python
x = 0
for i in range(1, 11):
    x += i
    print(x)

이러면 x에 i를 더하며 1부터 10까지 더한다.


<예시2 - 이중 for>
#!syntax python

for i in range(2, 10):
    x = 0
    print(f"------ {i}단 -----")
    for j in range(1, 9):
        x = i * j
        print(f"{i} x {j} = {x})

위 코드는 이중 for 문을 사용 해 구구단을 출력하는 코드이다.

<예시>
#!syntax python
n = int(input("시작할 숫자를 입력하세요 ----> ")
m = int(input("끝낼 숫자를 입력하세요 ----> ")
for i in range(n, m + 1):
    print(i)

위 코드는 n과 m을 입력받아 n부터 m까지의 숫자를 출력하는 코드이다.

6.2. while 문

#!syntax python
while C:
    todo

위 코드는 C라는 조건이 만족되는 동안 todo를 계속 실행하며, 해당 조건이 더 이상 만족되지 않으면 while문을 탈출한다. C라는 조건이 항상 참이면 무한 루프에 걸릴 수 있으니 주의. 이를 이용해서 계속해서 반복해서 작동해야하는 프로그램의 경우에 while True문을 이용하기도 하며, 1을 논리형으로 변환하면 True가 되므로 while 1: 로 사용하는 경우도 있다.

<예시>
#!syntax python
i = 0
while i < 10:
    print(i)
    i += 1

위 코드는 i가 10보다 작은 동안 i를 출력한 다음 1씩 증가시키므로, 0부터 9까지의 정수를 한 줄에 하나씩 출력한다.

<예시>
#!syntax python
n = 0
m = 124
count = 0
while n != m:
    n = int(input("숫자를 맞혀보세요 ---->"))
    count += 1
    if n > m:
        print("조금만 더 작게 해보세요.")
    if n < m:
        print("조금만 더 크게 해보세요.")
    if n == m:
        print("축하합니다! 정답입니다!")
    if count == 10:
        print("Hint : 100~130 이내")

이러면 사용자가 m을 맞출 때 까지 반복되고, 10번 시도하면 힌트를 알려준다.

7. 함수

7.1. 일반 함수

Python의 함수 정의 키워드는 def이다. 예시를 보자.
<예시>
#!syntax python
def hello():
    print("Hello?")

hello()

이러면 Hello?라는 문자열이 출력된다.
함수의 이름은 파이썬의 기본 함수[5]로는 지정 할 수 없으며, 한글 이름과 숫자로 시작하는 이름은 입력 할 수 없다. 그리고 _를 제외한 특수 문자가 포함되게 할 수 없다.

그리고 인자라는 매개 변수를 줄 수 있다. 예시를 보자.
#!syntax python
def name_hello(name):
    print(f"{name} : hello?

name_hello("smith")

이러면 smith : hello? 라는 문자열이 출력된다.

return은 말그대로 반환값이다. 처음에는 함수 안에 명령어를 넣으면 되니 필요 없는 거 아닌가?라는 생각이 들 수 있으나, 아래 예시를 보면 생각이 바뀔 것이다.

<예시>
#!syntax python
def multiply(a, b):
    return a*b

print(multiply(4, 4)

이 함수는 4와 4를 곱한 값인 16을 출력한다. print에 함수로 구해진 값인 16을 건네줘서 출력하는 거다.

하지만 굳이 인자를 가져오지 않아도 global 이라는 명령어를 사용하여 함수 안에서도 전역변수 사용을 명시할 수 있다. [6]다만 전역 변수는 모두 공통으로 사용하는 변수라, 상황에 따라 필요 할 때만 쓰는 것이 좋다.
#!syntax python
a = 3
b = 5
def multiply():
    global a, b
    return a*b

print(multiply())

이 예시의 결과는 15이다. 만약 여기서 global을 뺐다면 오류가 났을 것이다.

정리하자면 Python에서의 함수의 종류는 총 4가지가 있다. 하나는 인자와 반환값이 없는 함수, 인자만 있는 함수, 반환값만 있는 함수, 인자와 반환값 둘 다 있는 함수이다.
함수의 인자로 입력된 변수는 함수 내에서만 사용 가능하다. 이걸 해결하기 위해 위의 global이 있는 것이다.

Asterisk를 2개 붙인 것은 키워드 변수를 의미한다. 이때, (키워드 - 값)의 딕셔너리 형태가 된다. 이때, 키워드는 str이다.
#!syntax python
def function(**kwargs):
    print(kwargs)

function(a = 1, b = 2) # {'a': 1, 'b': 2}를 출력한다.


일반 변수, 키워드 변수, asterisk를 붙인 변수, double asterisk를 붙인 변수가 모두 있다면, 키워드 > 일반 > ** 변수 > * 변수 순서로 인식된다.
#!syntax python
def function(a, b = 0, *args, **kwargs):
    print("a =", a)
    print("b =", b)
    print("args = ", args)
    print("kwargs =", kwargs)

function(1, 2, 3, b = 4, i = 5)

결과:
#!syntax python
a = 1
b = 4
args = (2, 3)
kwargs = {'i': 5}

7.2. 람다 함수

람다 함수도 사용 가능하다. 람다 함수는 익명 함수를 뜻하며, 선언한 즉시 함수 그 자체가 되어 실행 가능하다.

#!syntax python
square = lambda n: n**2
square(5) #25

함수도 일종의 객체로 취급하기 때문에 변수에 담거나 인자로 넘길 수 있다.

변수가 여럿이면 ,로 구분하면 된다.
#!syntax python
add = lambda m, n: m+n


아예 변수가 없어도 된다. 이 경우 :의 왼쪽을 비우면 된다.
#!syntax python
one = lambda: 1


타 언어와 달리 파이썬의 람다 함수는 한 줄밖에 쓸 수 없으니 참고해야 한다.

7.2.1. 응용

Python에서 람다 함수의 사용은 가독성을 헤치므로 추천되지 않는다. (PEP 8)
다만, 람다 함수의 적절한 사용은 편의성을 높여주므로 가독성을 헤치지 않는 정도로 적절히 사용하는 것이 좋다.

예를 들어, map 함수[7]나 functools 모듈의 reduce 함수와 lambda 함수의 궁합이 좋다.
map은 iterable한 자료형으로, 함수와 다른 iterable한 객체으로 만든다.
#!syntax python
arr = map(func, iter)
arr[i] == func(iter[i]) #True


reduce는 이변수함수와 iterable한 객체를 인자로 받는 함수이다. reduce의 작용은 대략적으로 다음과 같다.
#!syntax python
def reduce(func, iter)
    x = iter[0]
    for i in iter[1:]:
        x = func(x, i)
    return


이를 lambda 함수와 함께 사용하면 다음과 같이 사용할 수 있다.
#!syntax python
arr = list(map(lambda x: x**3, range(7)))

print(arr) # [0, 1, 8, 27, 64, 125, 216]

import functools
total = functools.reduce(lambda x, y: x+y, [1, 3, 4])

print(total) # 1 + 3 + 4 = 8

8. 슬라이싱

파이썬에서는 슬라이싱이라는 매우 편리한 기능을 제공한다. 무엇보다 내부적으로 매우 빠르게 동작한다. 위치를 지정하면 해당 위치의 배열 포인터를 얻게 되며 이를 통해 연결된 객체를 찾아 실제 값을 찾아내는데, 이 과정은 매우 빠르게 진행되므로 리스트나 문자열을 조작할 때는 항상 슬라이싱을 우선으로 사용하는 편이 속도 개선에 유리하다.
파일:2-6-1.png
<rowcolor=#373a3c> 문법 결과 설명
S[1:4] 녕하세 인덱스 1에서(0부터 시작) 4 이전까지(4는 포함하지 않는다) 표현한다. 4개를 의미하는 게 아니므로 유의해야 한다.
S[1:-2] 녕하 인덱스 1에서 -2 이전까지(-2는 포함하지 않는다) 표현한다. 뒤에서부터는 음수로 접근이 가능하다.
S[1:] 녕하세요 문자열의 시작 또는 끝은 생략 가능하다.
S[:] 안녕하세요 둘 다 생략하면 사본을 리턴한다. 파이썬은 a=b와 같은 형태로 할당하면 변수의 값이 할당되는 것이 아니라 a 변수가 b 변수를 참조하는 형태가 된다.
참조가 아닌 값을 복사하기 위해[:]를 사용할 수 있으며, 이 방식은 문자열이나 리스트를 복사하는 파이썬다운 방식(Pythonic Way)이기도 하다.
S[1:100] 녕하세요 인덱스가 지나치게 클 경우 문자열의 최대 길이만큼만 표현된다. S[1:] 과 동일하다.
S[-1] 마지막 문자(뒤에서 첫 번째)
S[-4] 뒤에서 4번째
S[:-3] 안녕 뒤에서 3개 글자 앞까지
S[-3:] 하세요 뒤에서 3번째 문자에서 마지막까지
S[::1] 안녕하세요 1은 기본값으로 동일하다.
S[::-1] 요세하녕안 뒤집는다.
S[::2] 안하요 2칸씩 앞으로 이동한다.

8.1. map

map 함수[8]는 매우 편리하게 입력을 받을 수 있다.
다음은 숫자 여러개를 입력받아 a라는 리스트에 넣어주는 코드이다.
a=list(map(int,input().split()))

이 코드는 입력을 나누어 주고 int형식으로 바꾼 map 오브젝트를 list로 바꾸어 준 것이다.

9. 예외 처리

#!syntax python
try:
    # 정상 작업
except BaseException as e:
    # 예외를 처리하기 위해 수행할 작업
else:
    # 예외가 발생하지 않았을 때 수행할 작업
finally:
    # 예외 여부에 관계없이 반드시 수행할 작업
여느 프로그래밍 언어와 비슷하게 예외 처리를 지원한다. 예외를 던질 때에는 raise 키워드를 사용한다.

10.

  • 문자열을 합칠 때 join을 쓰자. range 함수와 str 함수를 같이 쓰면 매우 편해지는 경우가 있다.

    • {{{#!syntax python
''.join(str(x) for x in range(10))
}}}
  • 슬라이스(slice) 문법은 리스트/문자열의 부분을 잘라내는 것 이외에도 다양한 활용이 가능하다.

    • {{{#!syntax python
# 문자열 뒤집기
a = 'abc'
print(a[::-1]) # 출력: cba

# 리스트 복사
a = [1, 2, 3]
b = a[:]
print(b) # 출력: [1, 2, 3]
print(a is b) # 출력: False

c = 1, 2], [3, 4
d = c[:]
c[0] = [5, 6] # 리스트 자체는 복사되지만
c[1][0] = 7 # 리스트의 원소들까지 복사되지는 않으므로 주의해서 사용하자.
print(c) # 출력: 5, 6], [7, 4
print(d) # 출력: 1, 2], [7, 4
print('%s, %s, %s' % (c is d, c[0] is d[0], c[1] is d[1])) # 출력: False, False, True
}}}
  • 숫자, 문자, 튜플은 변경 불가능(immutable)하며, 리스트, 집합, 딕셔너리는 변경 가능(mutable)하다. 이때 변경 가능한 자료형은 다른 변수에 대입하여도 그 내용이 공유된다. 그 예로, 아래와 같은 코드가 있다고 하자.

    • {{{#!syntax python
a = (1, 2, 3)
b = a
b += (2, 1)
print(a) # 출력: (1, 2, 3)
print(b) # 출력: (1, 2, 3, 2, 1)
}}}
우리가 예상한 대로, 튜플 b만 변경되고, a는 변경되지 않는다. 위의 코드에서 튜플(immutable)을 리스트(mutable)로 바꾸어 보자.
{{{#!syntax python
a = [1, 2, 3]
b = a
b += [2, 1]
print(a) # 출력: [1, 2, 3, 2, 1]
print(b) # 출력: [1, 2, 3, 2, 1]
}}}
출력을 보면 b만 변경했음에도 a가 변한다는 사실을 알 수 있다. 이것은 모든 변경 가능한 자료형에 적용되며, 심지어 리스트 안의 리스트 같은 것들까지도 공유가 된다. 그러니 원본을 변경하면 안 되는 경우에는 list(), set(), dict()나 copy 모듈 등을 이용해서 객체를 복제하고 작업하자. 변경 불가능한 자료형은 원본을 변경할 수 없기 때문에 해당 사항이 없다.
특히 list나 dict 자체를 함수에 인자로 전달받을 때 내부에서 리스트를 변형하는 연산을 하면 함수 밖에서도 list나 dict가 변형되니 주의하도록 하자.
  • list.insert(0) 와 list.append()는 각각 첫 번째 자리에 값을 추가하거나, 마지막 자리에 값을 추가하는 정도의 조그만한 차이일 뿐이지만, 계산 시간이 O(N)과 O(1) 수준으로 차이가 나기 때문에 첫 번째 방법은 쓰지 않는 것이 좋다.
    그래서 prepending에 의존하는 하는 알고리즘을 파이썬 리스트로 구현하려면, 알고리즘을 거꾸로 뒤집는 것이 좋고, 만약 알고리즘을 뒤집기 힘들다면, 파이썬 공식 라이브러리에서 제공하는 deque 같은 것을 써야 한다. 자료구조 개념에 대한 감각이 있으면 이해하기 쉽다.
    CPython같은 경우 JIT를 쓰지 않기 때문에 이런 것을 자동으로 최적화해 준다고 생각하지 말자.
  • 괄호 안에 for 과 if, else 를 넣을 시 주의하자.

    • {{{#!syntax python
#1
list(x for x in range(10) if x%2 == 0)
#2
list(x for x in range(10) if x%2 == 0 else 0)
#3
list(x if x%2 == 0 else 0 for x in range(10))
}}}
1은 되지만 2는 되지 않으며 3은 된다. if만 넣을 경우 for 뒤에 써야 하며, 조건을 충족하지 않는 원소들은 생략된다(즉, 1의 결과물은 [0, 2, 4, 6, 8]이다). if와 else 모두를 넣는다면 for 앞에 넣어야 하며 조건을 충족하면 맨 앞, 아니라면 else 다음이 반환된다.
  • 마지막으로 호출된 값(대입이 이루어지지 않은 경우)은 _ 변수에 저장된다. 또한 이 변수에 대입한 값은 버려진다.
  • 멀티프로세싱은 \_\_main\_\_ 블럭 안에 들어가야 한다. 네임스페이스 문제 때문. 들어가지 않으면 오류를 뿜는다.

    • {{{#!syntax python
#if 대신 while도 가능.
if name == 'main':
}}}
  • 반복문을 사용할 때 유도 변수 (i, j 등)을 사용하지 않고 'for value in mylist'와 같이 사용할 수 있는 것은 python의 큰 장점이다. 그럼에도 불구하고 인덱스를 사용해야 하는 경우 'for i in range(len(mylist))'처럼 쓰거나 count 변수를 임시로 생성하지 말고 enumerate를 사용하자.

    • {{{#!syntax python
mylist = [10, 20, 30, 40]
# 이렇게 하지 말고,
for i, value in enumerate(mylist):
print(mylist[i])
...
}}}
  • 파이썬 2와 3에서의 range는 리턴 형식이 다르다. 2에서는 리스트를 리턴하지만 3에서는 range 객체를 리턴한다. 따라서 3에서 range를 리스트로 바꾸려면 아래와 같은 방법들로 전환해야 한다. 파이썬 2에 익숙한 사람은, 파이썬 3의 range는 파이썬 2의 xrange와 동일한 역할을 한다고 생각하면 된다.

    • {{{#!syntax python
list(range(10))
[range(10)]
}}}
그 외에도 파이썬 2와 3은 정수 나눗셈, print 문법, 문자열 종류, import 방식 같은 데서 차이가 많이 나는 편이다. 일부는 __future__이라는 라이브러리에서 파이썬 2에서도 3과 같은 문법을 쓸 수 있도록 해 주는 기능을 제공하고 있지만, 그렇지 않은 부분들은 stack overflow등을 참고해서 직접 만들어서 쓰는 것이 좋다. 현재 많은 오픈 소스 라이브러리들이 __future__로 도배되어 있고 가내 수공업 식으로 호환성을 땜질해 있는 것을 보면 말이다. 파이썬 2.7이 공식적으로 지원이 중단되면 시점까지 많은 라이브러리들이 파이썬 2 지원을 철회할 계획을 가지고 있으므로, 그때가 되면 이런 호환성 문제에서 숨통이 트일 것이다.
  • Bolierplate 코드가 적고, 리스트와 셋, 해시 등의 자료구조를 간단한 기호로 표기할 수 있어 코딩 테스트 시 많이 사용되는 언어이기도 하다. Python으로 코드를 작성하면 같은 알고리즘을 C++, Java 등으로 구현했을 때보다 전체적인 코드 길이가 비약적으로 짧아진다.
  • 파이썬 인터프리터라도 열어서 아무 모듈이나 임포트하거나, print 함수에 대해 dir(print)를 입력해보면 파이썬의 구조를 좀 더 잘 알게 된다. 우리가 사용했던 함수가 다르게 보일 것이다.
  • 과학 계산 시 numpy를 자주 이용하는데, for문을 이용하기보다는 배열을 이용해 처리하는 vectorize 테크닉을 사용하자. 이것조차 안 된다면 numba라는 JIT 컴파일 라이브러리를 이용해서 성능을 향상시킬 수 있다.


[1] 단, 파이썬 3.6부터 기본 패키지인 typing을 사용하여 정적 타이핑이 가능하다.[2] 주로 다른 언어를 하다 Python으로 넘어오는 프로그래머들이 저지르는 실수이다.그러나 파이썬하다 다른 언어하면 대문자로 써서 오류난다[3] 예시: int(input()) 이러 써놓고 문자열이 입력될 시[4] 그렇다고 print(range(10)) 식으로 적으면 출력되지 않는다.[5] print, def, input, if, on, in 등[6] 명시한다고 표현한 이유는 함수가 정의될 때 스코프에 전역변수를 포함하기 때문이다. 하지만 함수 내에서 값을 수정하면 실제 전역변수는 수정되지 않아 global 키워드로 수정할 수 있다.[7] 사실은 클래스이지만[8] 사실은 클래스이다. int도 클래스이지만 int(*)로 실수를 버림하거나, 문자열을 정수로 바꾸는 것과 마찬가지. 물론 파이썬은 순수 객체지향 언어이기에 map이 클래스냐 함수냐 따지는 것은 크게 의미가 없다.[range(10)]