파이썬 프로그래밍 기초 1부 1편

주요 내용

기본 문법

들여쓰기

들여쓰기를 이용하여 명령문 블록(block)을 지정한다. 예를 들어, for 반복문의 본문에 if ... else ... 조건문을 사용하고자 할 경우 아래와 같이 작성한다.

for x in array:
    if x < pivot:
        less.append(x)
    else:
        greater.append(x)

참고: 들여쓰기는 Tab 키를 이용하며 보통 스페이스 네 개에 해당한다. 하지만 사용하는 편집기에 따라 다를 수 있다.

세미콜론

모든 명령문은 한 줄에 완성하는 것이 기본이며, 연속된 명령문은 줄바꿈을 해서 작성한다. 하지만 매우 간단한 명령문을 한 줄에 연속으로 작성할 경우 사용할 수 있는데 이때 세미콜론(;)을 사용한다.

세미콜론 사용은 자제하는 게 좋다. 아래와 같이 줄바꿈을 하여 각각의 명령문을 명확하게 작성하는 것을 추천한다.

연속된 변수 할당의 경우 파이썬은 아래 방식도 지원한다.

주의사항: f"..." 형식은 문자열 템플릿을 가리킨다. 문자열 템플릿은 문자열의 특정 위치에 변수값을 입력할 수 있는 기능을 갖는 문자열이다. 위에서 사용된 템플릿은 f-문자열이며, 나중에 설명할 format-문자열과 함께 가장 유용한 문자열 템플릿이다.

객체

파이썬이 다루는 대상(값)은 모두 객체(object)이다. 즉, 모든 값은 특정 클래스의 인스턴스이라는 의미이다. 따라서 값과 관련된 메서드(methods)가 존재하며 이런 메서드들을 적절하게 활용하면서 프로그램을 작성할 수 있어야 한다.

여기서는 앞으로 수(numbers), 문자열(strings), 리스트(lists), 넘파이 어레이(numpy arrays), 팬다스 데이터프레임(pandas dataframes) 등의 메서드의 활용법을 익혀나갈 것이다.

주석

샵 기호(#) 다음에 오는 문장은 파이썬 인터프리터에의 의해 무시된다. 주로 코드의 일부 기능을 잠시 해제하거나 코드에 대한 설명을 전달하는 주석으로 활용된다.

예를 들어 아래는 코드의 일부를 해제하는 기능으로 사용되었다.

주석을 제거하면 다른 결과가 나올 수 있다. 이유는 if 조건문에 의해 빈 문자열(empty string)은 무시되기 때문이다.

참고: continue 명령문의 기능은 잠시 뒤에 자세히 설명한다.

반면에 아래와 같이 명령문 끝 부분에 주석을 달아 해당 명령문에 대한 설명 또는 정보를 제공하기도 한다.

함수 호출

함수를 적절한 인자와 함께 실행하는 것을 함수 호출이라 한다. 예를 들어, 아래와 같이 세 개의 인자를 받는 함수는 세 개의 매개변수를 이용하여 선언한다.

함수 f를 호출하려면 인자 세 개를 지정해야 한다. 아래 코드에서는 정수 세 개를 이용하여 함수를 호출하고 함수가 실행하면서 반환한 값을 변수 result에 할당하였다.

함수가 반환하는 값과 저장된 값이 동일함을 아래와 같이 확인할 수 있다.

특정 객체의 메서드를 호출하는 방식도 기본적으로 동일하다. 다만, 객체의 이름과 함께 아래 방식으로 호출되어야 한다. 예를 들어, 아래 코드는 리스트에 항목을 추가하는 append() 라는 리스트 메서드의 활용법을 보여준다.

참고: 메서드는 특정 클래스 또는 해당 클래스의 인스턴스, 즉, 해당 클래스의 객체에서만 사용할 수 있는 함수이다.

함수 인자

함수의 인자는 크게 두 종류로 나뉜다.

예제: print() 함수의 키워드 인자

print() 함수는 출력 대상인 인자는 위치 인자로 지정해야 하고, 키워드 인자는 출력 방식에 대한 옵션을 지정할 때 사용된다.

키워드 인자를 사용하지 않으면 여러 인자를 스페이스로 구분하여 한 줄에 출력한다.

sep 키워드 인자는 출력되는 인자들을 구분하는 방식을 지정하며 기본값은 앞서 본대로 스페이스이다. 이를 예를 들어 쉼표와 스페이스로 지정하는 방식은 다음과 같다.

end 키워드 인자는 모든 출력을 마친 후에 추가로 할 일을 지정한다. 기본 값은 줄바꿈이다.

하지만 줄바꿈을 예를 들어 쉼표 스페이스로 대체하면 다음과 같이 작동한다.

반드시 위치 인자를 모두 지정한 다음에 키워드 인자를 위치해야 하며, 키워드 인자들 사이의 순서는 중요하지 않다.

예제: 키워드 인자를 갖는 함수 정의하기

print() 함수 이외에도 파이썬에서 기본으로 제공하는 많은 함수가 키워드 인자를 사용한다. 나중에 배울 넘파이에서 제공되는 다수의 함수처럼 특히 데이터 분석에 사용되는 많은 함수가 그러하다. 여기서는 키워드 인자를 사용하는 함수를 정의하는 방식을 간단한 예제를 통해 살펴본다.

온라인 서점에서는 책을 정가의 10%를 할인해서 판매한다. 그런데 특별한 날엔 정가의 20%를 할인해주는 행사를 진행한다고 가정하자. 이때, 일반적으로 10%의 할인을 적용하다가 행사가 진행되는 20%를 할인하는 함수를 다음과 같이 정의할 수 있다.

이제 정가 23,000원인 책을 구입할 때 실제로 지급해야 하는 값은 10% 할인된 20,700원이다.

이제, 예를 들어, 여름 특별 행사로 인해 20%를 할인해 준다고 가정하자. 그러면 정가 23,000원에 대해 지불해야 하는 값은 18,400원이다.

주의사항: 위 코드의 discount=discount에서 왼편 discountbook_price() 함수를 선언할 때 사용된 키워드, 즉, 기본값이 있는 매개변수이다. 반면에 오른편 disconnt는 바로 윗줄에 선언된 변수이다.

참조 변수

변수가 리스트와 같이 좀 복잡한 객체를 가리킬 때는 참조(reference) 기능을 사용한다.

아래와 같이 하면 변수 b 가 변수 a가 동일한 값을 참조한다.

참고: 참조는 아래 그림에서 보여지듯이 화살표 형태로 다른 곳에 저장된 값을 가리키는 기능으로 이해하면 된다.

실제로 a가 참조하는 값을 변화시키면 b도 영향받는다.

반면에 아래와 같은 경우는 리스트를 참조하는 경우와 다르게 작동한다.

변수 a가 가리키는 값을 변경해서 변수 b에 영향을 주지 않는다.

전역 변수와 지역 변수

함수 밖에서 선언된 전역 변수(global variables)는 함수 내에서 사용할 수 있지만, 함수의 매개변수 또는 함수 본문 내에서 선언된 지역 변수(local variables)는 함수 밖에서 사용할 수 없다.

아래 코드에서 data는 함수 밖에서 선언된 전역 변수이기에 함수에 인자로 전달될 수 있다.

반면에 매개 변수로 지정된 element는 함수 실행이 멈춘 후에는 더 이상 사용할 수 없다.

동적 참조(dynamic reference)

변수에 할당된 값은 심지어 다른 자료형의 값으로 변경될 수 있으며, 그에 따른 자료형의 정보도 함께 변경되어 저장된다. 이렇게 작동하는 방식을 동적 참조라 한다.

강타입 대 약타입

파이썬의 모든 값은 특정 클래스의 객체라고 하였다. 따라서 사용되는 함수 또는 연산자에 따라 적절한 클래스의 객체를 사용하지 않으면 실행오류가 발생할 수 있다. 이처럼 사용되는 값의 자료형이 맞지 않을 경우 제대로 작동하지 않으면 강타입(strong types)라 부른다.

예를 들어 문자열과 숫자는 더할 수 없다.

반면에, 예를 들어, 부동소수점과 정수의 나눗셈은 정수를 부동소수점으로 강제로 형변환을 시켜서 실행된다.

이렇게 작동하는 언어를 약타입(weak types) 언어라 부른다. 파이썬은 기본적으로 강타입 언어이지만, 약간의 약타입을 지원하는 언어라는 의미이다.

객체의 자료형 활용

객체의 자료형에 따라 다른 일을 지정할 수도 있다. 이를 위해 먼저 객체의 자료형이 지정된 자료형인지 확인하는 기능이 필요하다.

예를 들어, a가 가리키는 값이 정수형의 값인지를 다음과 같이 확인한다.

그리고 부동소수점의 자료형인가를 확인하려면 다음과 같이 한다.

여러 자료형 중의 하나인가를 확인하려면 여러 자료형을 튜플로 작성하여 사용한다. 예를 들어, 정수 또는 부동소수점 중의 하나의 값인가를 확인하려면 다음과 같이 한다.

객체의 속성과 메서드

모든 객체는 속성(attributes)과 메서드(methods)를 갖는다.

탭 키(Tab)를 이용하면 주어진 객체의 모든 속성과 메서드를 확인할 수 있다.

In [1]: a = 'foo'

In [2]: a.<Tab>
a.capitalize  a.format      a.isupper     a.rindex      a.strip
a.center      a.index       a.join        a.rjust       a.swapcase
a.count       a.isalnum     a.ljust       a.rpartition  a.title
a.decode      a.isalpha     a.lower       a.rsplit      a.translate
a.encode      a.isdigit     a.lstrip      a.rstrip      a.upper
a.endswith    a.islower     a.partition   a.split       a.zfill
a.expandtabs  a.isspace     a.replace     a.splitlines
a.find        a.istitle     a.rfind       a.startswith

속성과 메서드를 확인하기 위해 getattr() 함수를 활용할 수도 있다. 예를 들어, 문자열의 split() 메서드를 확인하면 아래의 결과를 보여준다.

즉, split 은 함수(function), 즉, 메서드임을 확인해준다.

덕 타이핑(Duck typing)

덕 타이핑은 "특정 기능을 지원하는가만 중요하다"는 의미를 전달할 때 사용하는 표현이다. ("오리처럼 꽥꽥 울기만 하면 그것은 오리다" 라는 의미에서 만들어진 표현임)

예를 들어, 문자열, 튜플, 리스트 등 처럼 각 항목을 차례대로 순환할 수 있는 값은 __iter__() 메서드를 가지며, 이런 객체를 이터러블(iterable) 객체라 부른다. 즉, 어떤 객체이든 __iter__() 메서드만 지원하면 순환기능을 사용할 수 있으며, 그런 객체를 이터러블이라고 부른다.

아래 함수는 이터러블 객체인지 여부를 판단해준다.

참고: iter() 함수는 인자가 __iter()__ 메서드를 갖고 있다면 그 메서드를 호출하고, 아님면 오류를 발생시킨다.

정수는 이터러블하지 않다.

isiterable() 함수를 이용하여 리스트는 아니지만 이터러블한 값을 모두 리스트로 형변환 시켜주는 함수를 아래와 같이 구현할 수 있다.

이제 문자열과 튜플을 리스트로 변환할 수 있다.

참고: toList() 함수는 사실 list() 함수와 동일한 기능을 수행한다.

모듈 불러오기

모듈(module)은 파이썬 소스코드를 담고 있는, 확장자가 .py인 파이썬 스크립트 파일이다.

다음 내용을 담은 모듈 some_module.py가 현재 주피터 노트북이 실행되고 있는 디렉토리에 저장되어 있다고 가정하자.

# some_module.py
PI = 3.14159

def f(x):
    return x + 2

def g(a, b):
    return a + b

주의사항: 구글 코랩에서 아래 코드를 실행하려면 먼저 some_module.py 파일을 구글 코랩에 업로드 해야 한다. 아니면 아래 코드를 실행해서 해당 코드를 다운로드할 수도 있다.

모듈 some_module을 불러와서(import) 그 안에 정의된 함수와 변수를 사용하는 방법은 다음과 같이 모듈이름과 함께 사용한다.

모듈에서 특정 변수와 함수만을 불러오면 모듈 이름을 사용할 필요가 없다.

모듈에 별칭을 주려면 as 예약어를 사용하여 지정한다.

함수 또는 변수만 따로 불러올 때에서 별칭을 줄 수 있다. 역시 as 예약어를 이용한다.

이항 연산자와 비교문

사칙연산과 비교문의 사용법은 일반적으로 알려진 방식과 동일하다.

부등호 연산자는 여러 개를 종합하여 사용할 수도 있다.

파이썬에서 지원하는 주요 이항 연산자는 다음과 같다.

이항 연산자 설명
a + b a와 b를 더한다
a - b a에서 b를 뺀다
a * b a와 b를 곱한다
a / b a를 b로 나눈다
a // b a를 b로 나눈 몫을 계산한다
a ** b a의 b승을 구한다
a == b a와 b가 동일한 값을 가리키는지 여부 판단
a != b a와 b가 서로 다른 값을 가리키는지 여부 판단
a < b a가 b보다 작은지 여부 판단
a <= b a가 b보다 작거나 같은지 여부 판단
a > b a가 b보다 큰지 여부 판단
a >= b a가 b보다 크거나 같은지 여부 판단
a is b a와 b가 동일한 위치에 저장된 값을 참조하는지 여부 판단
a is not b a와 b가 다른 위치에 저정된 값을 참조하는지 여부 판단

is==의 차이

세 개의 변수 a, b, c를 아래처럼 선언하자.

앞서 참조에 대해서 설명한 것처럼 각 변수가 참조하는 리스트는 아래 그림에서와 같다.

먼저, is 연산자는 동일한 위치에 저정된 값을 참조하는지 여부를 결정한다. 예를 들어, ab는 동일한 리스트를 참조한다.

반면에 ac는 서로 다른 리스트를 참조한다.

참고: is not은 서로 다른 위치에 저정된 값을 참조할 때 참이다.

반면에, == 연산자는 두 변수가 참조하는 값이 동일한 값인지 여부를 판단한다. 예를 들어, 두 변수 a, c가 비록 서로 다른 위치에 저정된 값을 참조하기는 하지만 참조된 두 값 모두 리스트 [1, 2, 3] 으로 동일한 값이다.

아래는 당연히 성립한다.

!===와 반대로 작동한다.

참고: 앞서 언급된 산술 연산자 이외에 논리 연산자, 비트 연산자가 사용된다. 논리 연산자는 아래에서 좀 더 살펴볼 예정이지만 비트 연산자는 여기서는 다루지 않는 대신에 파이썬 코딩도장: 비트 연산자 사용하기를 추천한다.

변경 가능한(mutable) 객체와 변경 불가능한(immutable) 객체

리스트, 사전, 넘파이 어레이 등은 변경이 가능한 자료형이다.

예를 들어, 리스트의 항목을 교체할 수 있다.

리스트에 새로운 항목을 추가할 수도 있다.

반면에 문자열과 튜플은 항목 수정이 불가능하다.