파이썬에서 심볼릭 (symbolic) 수학을 지원하는 sympy 라는 모듈이 있다. winPython을 사용한다면 기본적으로 설치되어 있으므로 사용하고 싶다면


>>> import sympy as sp

라고 하면 된다. 흥미로운 것은 수학 계산식을 LaTex 스타일로 깔끔하게 표시할 수 있다. 이를 위해서는 다음과 같은 이 모듈 내의 함수를 호출하면 된다.

>>> sp.init_printing() # 수식을 LaTex 스타일로 표시한다.


만약 배경색을 검은 색으로 사용하고 있다면 다음과 같이 글자색을 흰색으로 지정해 줄 수 있다.


>>> sp.init_printing(forecolor='White')

이 함수를 맨 처음 실행시킬 때는 별도의 패키지를 인스톨하라는 대화창이 뜨며 한 번만 인스톨해주면 된다. 이렇게 하면 이후에 수학식이 LaTex 스타일로 굉장히 깔끔하게 표시된다. 예를 들면 아래와 같다.


유니코드를 사용하여 수식을 표시하는 함수로 pprint()가 있다. 만약 아스키코드로만 표시하고 싶다면 use_unicode = False 옵션을 주면 된다.


>>> expr = sp.sqrt(x/(x**2+1))+sp.pi
>>> sp.pprint(expr) # 유니코드를 이용하여 수식 표시
         ________    
       ╱   x        
     ╱  ──────  + π
   ╱    2         
╲╱    x  + 1     
>>> sp.pprint(expr,use_unicode=False) #아스키코드로 수식 표시
    ________     
   /   x         
  /  ------  + pi
 /    2          
\/    x  + 1      


 그런데 sympy 에는 init_session() 이라는 함수가 있는데 이 함수의 옵션으로 ipython=True 를 주면 sympy 모듈이 전역 공간으로 임포트되며 LaTeX 모드가 활성화된다.

init_session()함수를 호출하면 내부에서 from sympy import * 가 수행되므로 이 모듈의 모든 함수/변수가 전역 공간에 올라온다. 따라서 이후에는 ipython 콘솔을 sympy 위주의 쉘로 활용할 수 있다.

다른 방법으로 위와 같이 명령어로 입력하지 않고 설정창에서 지정해 줄 수 있다.


만약 sympy 위주로 쉘을 사용하고 싶다면 이 옵션을 지정해 주는 것도 좋을 것이다.

하지만 sympy 도 다른 모듈들(numpy 등)과 구분하여 사용하고 싶다면 맨 처음에 소개한 명령어를 사용하는 것이 좋다.

>>> import sympy as sp
>>> sp.init_printing() # LaTex 스타일로 수식 표시

 ipython의 매직 명령어인 %matplotlib inline 이라고 하면 ipython 창에 그래프를 그려준다.


>>> %matplotlib [gui]


여기서 [gui] 옵션으로 inline, gtk4, qt4 등을 줄 수 있으며 inline 을 주면 ipython 창 내부에 그래프를 도시해 준다. 이후에 예를 들어 sympy.plot() 함수 등을 사용하면 ipython 내부 창에 그래프를 띄워준다.

 만약 초기에 이러한 설정으로 시작하고 싶다면 옵션으로 지정하여 ipython 창이 생성될 때 자동으로 설정되도록 할 수 있다. 아래 그림과 같이 Support for graphics (Matplotlib) 항목 내의 Active support 를 체크하면 ipython 이 시작될 때 그래프 기능을 활성화시킨다.

단 이 옵션은 자동으로 numpy 와 matplotlib.pyplot 모듈을 np, plt 이름으로 임포트시킨다. 이것은 dir() 명령으로 확인할 수 있다.


 두 번째 항목인 automatically load pylab 은 비활성화시키기를 권장한다. pylab 은 내부에서 numpy와 matplotlib.pyplot 등의 모듈들을 전역공간으로 임포트하여 함수들을 관리하는데 혼동을 주기 때문이다.



Posted by 살레시오
,

1. 개요

 상미분방정식(이하 상미방)의 수치 적분을 수행하기 위해서 scipy.integrate.odeint 함수의 사용법에 대해서 알아보도록 하겠다. scipy.integrate 클래스는 적분을 수행하는 다양한 함수들이 모여 있는데 그 중 연립 상미방의 수치적분을 구하는 ode, odeint, complex_ode 함수들이 마련되어 있다.

 

  • odeint             : 상미방의 수치적분

  • ode                : 상미방의 수치적분 (generic interface class)

  • complex_ode  : 복소 상미방의 수치적분

 

이중 odeint 는 내부적으로 FORTRAN 라이브러리인 odepack 의 'lsoda'를 사용하여 상미방을 풀어내는 함수이다. 이 함수는 (연립) 상미분 방정식

  • y' = f ( y, t )

의 수치해를 구해주며 stiff ode 와 non-stiff ode 모두에 적용된다.

2. 기본 문법


 일단 레퍼런스의 함수 문법은 다음과 같다.


y, infodic = scipy.integrate.odeint (
   func,# callable(y, t, ...) : 시간 t 에서 y(t)의 미분값을 구할 수 있는 함수
   y0,  # array_like : y 의 초기 조건 (벡터도 된다.)
   t,   # array_like : y(t)값을 구할 t 점들. 초기값의 시간이 이 배열의 첫 요소여야 함.
   args=()  # 튜플 : func() 에 넘길 추가적인 인수들
   Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None,
   tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12,
   mxords=5, printmessg=0
)

 

여기서 필수적인 인수는 func, y0, t 세 개이며 각각 ODE함수, 초기값, 시간(벡터)이다. 나머지 인수들은 모두 선택적으로 지정해 줄 수 있으며 지정하지 않으면 설정값이 사용된다. 그리고 y0와 t는 리스트, 튜플, ndarray (이것들을 묶어서 array_like 라고 한다.) 등이 될 수 있다.

 이 함수를 사용하기 전에 먼저 상미방을 기술하는 함수를 먼저 정의해야 한다. 이 함수는 array_like 를 반환해야 하며 ndarray y와 시간 t 를 받아서 그 미분을 구하는 함수이다.

 odeint() 함수의 출력 y는 배열(ndarray) 이고 shape 이 ( len(t), len(y0) ) 이며 2차 배열이다. 입력으로 넘어온 t 배열의 각 점에서의 y값들을 갖는다. 두 번째 출력인 infodict 는 full_output== True 로 지정되었을 경우 추가적인 정보가 넘어오게 된다.

3. 간단한 1차 ode 예제

 다음과 같이 가장 간단한 1차 미방을 시간 구간 [0, 5] 에서 수치해를 구하는 예제를 해 보도록 하겠다.


  • y' =  -2y, y(0)=1

위 예제에서는 pylab 모듈에 numpy가 포함되어 있으므로 따로 numpy는 import하지 않았다.

4. 2차 ode : 조화진동자

  조화 진동자 방정식은 2차 상미방으로서 x''(t) = -x(t) 이다. 2차 방정식은 두 개의 1차 방정식으로 분해할 수 있다. 즉, y(t) = [ x(t) ; x'(t) ] =: [y1(t); y2(t)] 라고 정의하면

              y'(t) = [x'(t); -x(t)] = [y2(t); -y1(t)]

와 같이 기술할 수 있다. 초기값이 [0; 1] 일 경우 시간 [0, 5]에 대해서 이 상미방을 풀면 다음과 같다. 이 예제에서는 ode1()함수의 반환값도 튜플이고 odeint()함수의 초기값도 튜플로 주었다.


Posted by 살레시오
,

 만약 x, y가 심볼로 등록이 되어 있다면 함수 y(x)의 x에 대한 미분은 sympy에서 다음과 같이 표현할 수 있다.


  • y(x) : 독립 변수 x에 대한 함수 y

  • y(x).diff() 혹은 y(x).diff(x,1) : 1차 미분

  • y(x).diff(x,2) : 2차 미분

  • y(x).diff(x,3) : 3차 미분


이것을 이용하면 상미분식을 표현할 수 있다. 예를 들면 다음과 같다.


[표 1] 미분식의 심파이 표현식 예

수식

심파이 표현식

y(x).diff() - cos(x)

y(x).diff(x,2) + 9*y(x) - exp(-2*x)

y(x).diff()-1-y(x)**2


함수를 표현할 때 y(x)와 같이 독립변수도 반드시 표기해야 함을 유의하자.


 dsolve()함수는 미분방정식을 풀어주는 sympy의 기본 함수이다. 첫 번째 인자로 미분식을, 두 번째 인자로 구할 함수를 적어주면 된다. 예를 들어서 다음과 같은 1차 상미방을 푼다고 가정하자.



이 미분방정식의 우변을 0으로 만들면 다음과 같다.



이제 dsolve 함수의 첫 번째 인자로 위 식의 좌변을 넣어주고 두 번째 인자로 y(x)를 인가하면 된다.



여기서 C1은 상수이다.  다른 미분 방정식을 풀어보자.



이 방정식도 우변을 먼저 0으로 만들어야 한다.



이제 이 식의 좌변을 dsolve()함수의 첫 번째 인자로 넣어준다.



2차 미분방정식도 입력할 수 있다. 예를 들어



을 풀려면 다음과 같이 하면 된다.



만약 함수의 미분표현식을 매번 입력하기 번거롭다면 다음과 같이 새로 정의하여 사용하면 된다.



이렇게 정의해 놓으면 이후부터는 y(x).diff() 대신 dy를, y(x).diff(x,2) 와 같이 긴 표현식 대신 ddy를 사용하면된다.



여기서 C1과 C2는 상수이다. 이것이 dsolve()함수를 이용한 미분방정식을 푸는 가장 기본적인 방법이다.



Posted by 살레시오
,

 심파이에서 행렬객체에 수행할 수 있는 선형대수 관련 연산을 다음 표에 정리하엿다.


[표 1] 선형대수 연산

연산

기능

A.T

A.H

A.D

전치행렬(transposition)

복소전치행렬(hermite conjugation)

Dirac transposition

A.rank()

행렬의 랭크(rank)

A.det()

행렬식 (determinant)

A.inv()

역행렬 (inverse matrix)

A.LUsolve(b)

행렬방정식 Ax=b 를 푼다.

A.norm()

norm을 구한다.

A.eigenvals(**flags)

A.eigenvects(**flag)

행렬의 고유값을 구한다.

행렬의 고유값과 고유벡터를 구한다.

A.evalf()

행렬 각 요소의 실수 근사값을 구한다.

A.applyfunc(f)

행렬 각 요소에 함수 f를 적용한다.


숫자로만 이루어진 행렬뿐만 아니라 대수 기호가 포함된 행렬에 대한 연산도 수행 가능하다.


>>> x=symbols('x') # x 를 기호로 설정
>>> C=Matrix([[x,2],[1,x]])
>>> D=ones(2)*x

>>> C
[x  2]
[1  x]

>>> D
[x  x]
[x  x]

>>> C.det()
2    
x  - 2

>>> C*D
[  2             2   ]
[x  + 2*x  x  + 2*x  ]
[   2           2    ]
[ x  + x    x  + x   ]


만약 대수 기호 대신에 숫자를 입력하고 싶다면 subs() 메쏘드를 이용한다.


>>> C.subs(x,11)
[11  2 ]
[1   11]

>>> y=symbols('y')

>>> D.subs(x,y**2+1)
[ 2       2    ]
[y  + 1  y  + 1]
[ 2       2    ]
[y  + 1  y  + 1]

>>> D.subs(x,sqrt(y))
[  ___    ___     ]
[\/ y     \/ y    ]
[  ___    ___     ]
[\/ y     \/ y    ]




Posted by 살레시오
,

 행렬 간 산술 연산은 +, -, *, ** 연산자로 수행할 수 있다. *은 행렬 간 곱셈을, **은 거듭제곱을 수행한다.


[표 1] 행렬의 기본 연산

연산

기능

A+B, A-B

행렬간 덧셈, 뺄셈

A*B

행렬간 곱셈 (A의 열 수와 B의 행 수가 같아야 한다.0

A**k

행렬 A의 k 거듭 제곱

v1.dot(v2)

벡터 v1과 v2의 내적(dot product)


덧셈과 곱셈은 두 행렬의 크기가 같아야 하고 행렬 간 곱셈은 차수 조건에 맞아야 한다. 즉, 첫 번째 행렬의 열 수와 두 번재 행렬의 행 수가 같아야 곱셈이 성립한다.


>>> A=randMatrix(3,4)
>>> B=randMatrix(4,2)

>>> A
[2   48  28  60]
[2   9   18  88]
[79  14  17  25]

>>> B
[10  49]
[47  95]
[18  67]
[60  59]

>>> A*B   
[6380  10074]
[6047  7351 ]
[3254  7815 ]

>>> B*A # 오류발생


 파이썬에서 **가 거듭제곱 연산자이므로 심파이에서도 행렬의 거듭제곱은 ** 연산자로 수행한다. 거듭제곱을 수행하려면 행렬이 정방행렬이어야 한다.


>>>  A=Matrix([[1,2],[2,3]])
⎡1  2⎤
⎣2  3⎦

>>> A**10
⎡514229  832040 ⎤
⎣832040  1346269⎦



Posted by 살레시오
,

  행렬 객체에 대해서 파이썬 인덱싱과 슬라이싱도 사용할 수 있다. 주의할 점은 수학의 행렬은 1행, 1열부터 시작하지만 Matrix객체는 인덱스가 0으로 부터 시작한다는 점이다. 따라서 첫 번째 행(열)의 인덱스는 0이고 두 번째 행(열)의 인덱스는 1이다.


>>> M = Matrix(2, 3, [1,2,3,4,5,6])
>>> M
[1 2 3]
[4 5 6]

>>> M[4] # 5
>>> M[1,2] # 6
>>> M[0,0] # 1
>>> M[1,1] # 5

>>> M[0:2, 0:2] # 2x2 부분 행렬
>>> M[1:2, 2]
>>> M[:,2] # 3열 전체


특정한 행이나 열을 뽑아내고 싶다면 row(n), col(n) 멤버 함수를 이용한다.


>>> M.row(0)
>>> M.col(2)
>>> M.row(-1) # 마지막 행을 뽑아낸다.


행렬 M의 복사본을 생성하고 싶다면 다음과 같이 하면 된다.


>>> M2 = M[:,:]
>>> M2[0,0]=100
>>> M


이와 같이 M2를 변경해도 M에는 영향을 미치지 않는다.


>>> M = Matrix(4,4,range(1,17))
⎡1   2   3   4 ⎤
⎢5   6   7   8 ⎥
⎢9   10  11  12⎥
⎣13  14  15  16⎦

>>> M[2,2] = M[0,3] = 0
>>> M
⎡1   2   3   0 ⎤
⎢5   6   7   8 ⎥
⎢9   10  0   12⎥
⎣13  14  15  16⎦

>>> M[2:, 2:] = zeros(2,2)
>>> M
⎡1   2   3  4⎤
⎢5   6   7  8⎥
⎢9   10  0  0⎥
⎣13  14  0  0⎦


행렬의 특정 행이나 열을 삭제하고 싶을 경우는 row_del(), col_del() 멤버함수를 이용하면 된다.


>>> M.row_del(0) # 첫 번째 행을 삭제한다.
>>> M.col_del(1) # 첫 번째 열을 삭제한다.


반대로 특정한 행이나 열을 끼워 넣고 싶다면 row_insert(n), col_insert(n) 을 이용한다. 이 경우 기존 행렬의 요소들을 밀어내고 그 위치에 입력한 행이나 열을 끼워 넣게 된다.


 그리고 A.row_join(B) 는 A행렬의 오른편에 B행렬을 병합시키고 A.col_join(B)는 A행렬의 하단에 B행렬을 병합시킨다.


>>> A=eye(3)
>>> A
⎡1  0  0⎤
⎢0  1  0⎥
⎣0  0  1⎦

>>> B=Matrix(3,2,range(11,17))
>>> B
⎡11  12⎤
⎢13  14⎥
⎣15  16⎦

>>> A.row_join(B)
⎡1  0  0  11  12⎤
⎢0  1  0  13  14⎥
⎣0  0  1  15  16⎦

>>> A.col_join(B.T)
⎡1   0   0 ⎤
⎢0   1   0 ⎥
⎢0   0   1 ⎥
⎢11  13  15⎥
⎣12  14  16⎦


또한 행렬객체의 메쏘드 중에 extract()라는 함수가 있다. 이것을 이용해서 원하는 부분을 뽑아낼 수 있다.


>>> A.extract(rowsList, colsList)


예를 들면 다음과 같다.


>>> M=Matrix(4,3,range(12))
>>> M
⎡0  1   2 ⎤
⎢3  4   5 ⎥
⎢6  7   8 ⎥
⎣9  10  11⎦

>>> M.extract([0,1,3],[0,1])
⎡0  1 ⎤
⎢3  4 ⎥
⎣9  10⎦


이 예를 보면 [0행, 1행, 3행] 과 [0열, 1열]이 겹치는 부부만 뽑아져 나온 것을 알 수 있다. 해당 행과 열에 선을 그어서 선이 겹치는 부분을 확인해 보면 쉽게 이해할 수 있을 것이다.



Posted by 살레시오
,

 심파이를 가장 간단하게 실행해 볼 수 있는 방법은 live.sympy.org 에 접속하는 것이다. 이 페이지에 접속하면 심파이의 최신 버전이 임포트된 파이썬 쉘을 사용할 수 있다.


[그림 1] live.sympy.org의 접속 화면


맨 처음 접속했을 때 상단에 보면 다음과 같이 미리 실행되는 명령들이 있다.


These commands were executed:
>>> from __future__ import division
>>> from sympy import *  
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)


 미리 실행되는 이  명령들에 의해서 심파이 모듈이 글로벌 환경에 임포트되어 있고 또한  변수 x, y, z, t 는 심파이의 대수 기호로 사용할 수 있다. 그리고 k, m, n은 정수 대수 기호 그리고 f, g, h 는 함수 기호로 바로 사용할 수 있다.


 만약 윈도를 사용하고 있고 로컬PC에서 심파이를 실행하고 싶다면 winpython을 사용하면 된다. 이 패키지는 파이썬과 필요한 모듈들이 대부분 포함되어 있으며 설치방식이 아니라 단순히 압축을 푼 후 실행하는 방식 (포터블)이라 사용하기 용이하다. 파이썬 2.x버전, 3.x 버전 각각 별도로 그리고 윈도 32bit, 64bit 버전별로 배포본이 마련되어 있다. 자기 환경에 맞는 것을 선택하여 다운로드하면 된다.


필자는 winpython 3.4.3.2 버전을 다운로드 받아서 실행하였다. 그러면 그 실행 파일의 하위 폴더에 다음과 같은 파일들이 생성되어 있다. 그 후 Spyder.exe를 실행하면 된다.


[그림 2] winpython의 설치 폴더


Spyder 가 실행된 후 Tools>Preferences 메뉴에서 다음 그림과 같은 항목을 체크한 후 ipython쉘을 실행시키면 바로 sympy를 사용할 수 있다.

[그림 3] winpython에서 sympy를 기본으로 실행시키기


이제는 로컬PC에서 ipython과 sympy를 사용할 수 있다.

[그림 4] winpython에서 ipython console을 실행시킨 화면



Posted by 살레시오
,

 다음 표는 산술/논리 연산에 관련된 내장 함수들이다.


[표 1] 산술/논리 연산에 관련된 내장 함수들

hex(n)

oct(n)

bin(n)

정수 n의 16진수 값을 구해서 ‘문자열’로 반환한다.

정수 n의 8진수 값을 구해서 ‘문자열’로 반환한다.

정수 n의 2진수 값을 구해서 ‘문자열’로 반환한다.

abs(n)

절대값을 구한다. 복소수의 경우 크기를 구한다.

pow(x,y[,z])

거듭제곱을 구한다. pow(x,y)은 x**y 와 같다.

divmod(a,b)

a를 b로 나눈 (몫, 나머지)를 구한다. 튜플 반환.

all(iterable)

any(iterable)

iterable 의 모든 요소가 True 일 경우 True를 반환.

iterable 의 하나 이상의  요소가 True 일 경우 True를 반환.

max(iterable)

max(arg1, arg2, …)

최대값을 구한다.

min(iterable)

min(arg1, arg2, …)

최소값을 구한다.

round()

반올림을 한다.


hex(), oct(), bin() 함수는 각각 ‘0x’, ‘0o’, ‘0b’ 로 시작하는 ‘문자열’로 결과를 반한한다. 이 문자열을 파이썬 값으로 변환하려면 eval()함수를 이용하면 된다.



Posted by 살레시오
,

 다음은 열거형(sequence)의 정보를 얻는 내장 함수들이다.


[표 1] 열거형의 정보를 얻는 내장 함수들

함수명

기능

len(seq)

시퀀스형을 받아서 그 길이를 반환한다.

iter(obj [,sentinel] )

next(iterator)

객체의 이터레이터(iterator)를 반환한다.

이터레이터의 현재 요소를 반환하고 포인터를 하나 넘긴다.

enumerate(iterable, start=0)

이터러블에서 enumerate 형을 반환한다.

sorted(iterable[,key][,reverse])

정렬된 *리스트*를 반환

reversed(seq)

역순으로 된 *iterator*를 반환한다.

filter(func, iterable)

iterable의 각 요소 중 func()의 반환값이 참인 것만을 묶어서 이터레이터로 반환.

map(func, iterable)

iterable의 각 요소를 func()의 반환값으로 매핑해서  이터레이터로 반환.


iter()은 seq형으로부터 이터레이터를 반환하는 함수이다. next()는 이터레이터의 현재 요소를 반환하고 이터레이터의 포인터를 그 다음 요소로 넘기는 함수이다.


enumerate()은 시퀀스로부터 enumarate형을 반환한다. 이것은 인덱스와 해당 값의 튜플을 반환하는 이터레이터를 가진다.


>>> seasons = ['spring','summer','fall','winter']
>>> list(enumerate(seasons))
[(0, 'spring'), (1, 'summer'), (2, 'fall'), (3, 'winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'spring'), (2, 'summer'), (3, 'fall'), (4, 'winter')]


보통은 for 문과 같이 사용되어서 반복문 안에서 이터러블의 요소값 뿐만 아니라 그 인덱스 정보도 필요할 경우 편리하게 사용할 수 있다.


>>> seasons=['spring','summer','fall','winter']
>>> for i,v in enumerate(seasons):
 …:    print("%s:%s"%(i,v))
  
0:spring
1:summer
2:fall
3:winter


filter(func, iterable)는 함수와 이터러블을 입력으로 받아서 이터러블의 요소가 하나씩 함수에 인수로 전달될 때, 참을 반환시키는 것만을 따로 모아서 이터레이터로 반환하는 함수이다.


 다음 예를 살펴보자.


def positive(l):
   result = []
   for i in l:
       if i > 0:
     result.append(i)
   return result

>>> print(positive([1,-3,2,0,-5,6]))
[1, 2, 6]


위의 positive함수는 리스트를 입력값으로 받아서 각각의 요소를 판별해 양수값만 따로 리스트에 모아 그 결과값을 돌려주는 함수이다.


 filter()함수를 이용하면 아래와 같이 똑같은 일을 동일하게 구현할 수 있다.


>>> def positive(x):
…      return x > 0
>>> print(list(filter(positive, [1,-3,2,0,-5,6])))
[1, 2, 6]


filter() 함수는 첫 번째 인수로 함수명을, 두 번째 인수로는 그 함수에 차례로 들어갈 이터러블(리스트, 터플, 문자열 등)을 받는다. filter 함수는 두 번째 인수인 이터러블의 각 요소들이 함수에 들어갔을 때 리턴값이 참인 것만을 이터레이터로 묶어서 돌려준다. 위의 예에서는 1, 2, 6 만이 양수로 x > 0 이라는 문장이 참이 되므로 [1, 2, 6]이라는 결과 값을 돌려주게 된다.


익명함수(lambda)를 쓰면 더욱 간편하게 쓸 수 있다.


>>> list(filter(lambda x: x > 0, [1,-3,2,0,-5,6]))
[1, 2, 6]


 filter()와 유사한 map() 함수가 있다. 이것은 함수와 이터러블을 입력으로 받아서 각각의 요소가 함수의 입력으로 들어간 다음 나오는 출력값을 묶어서 이터레이터로 돌려주는 함수이다. 만약 어떠 리스트의 모든 요소의 제곱값을 갖는 새로운 리스트를 만들고 싶다면 다음과 같이 하면 된다.


>>> a = [2, 3, 4, 7, 8, 10]
>>> a2 = list(map(lambda x:x**2, a))
[4,9,16,49,64,100]


파이썬 2.7은 filter()와 map()의 결과가 리스트이므로 위 예에서 list함수를 이용하여 리스트로 변환하지 않아도 된다. 파이썬 3.x에서는 이들 함수의 반환값이 리스트가 아닌 반복형(iterable)이므로 이것을 리스트로 만들기 위해서는 list()함수를 명시적으로 사용해야 한다.



Posted by 살레시오
,

  이전 포스트에서 객체를 생성하는 것이 외형상으로 함수를 호출하는 것과 유사하다고 했는데, 사실 객체를 생성할 때 클래스의 __init__() 메소드를 호출하게 된다. 이 메쏘드는 다음과 같이 사용자가 정의할 수 있다.


class 클래스명:
def __init__(self):
메소드 본체


이 예에서 __init__(self) 메쏘드는 객체를 생성할 때 자동으로 호출되는 특수한 메소드이고 반드시 첫 번째 인자는 self 이어야 한다. 이 메쏘드 내부에 클래스 변수를 생성할 수 있다.


class Robot:
   def __init__(self):
       self.nLegs = 2
       self.nArms = 2


이제


>>> asimo = Robot()


이라고 Robot객체를 생성하면 nLegs 와 nArms 필드가 생성되고 초기화 되었음을 알 수 있다.


>>> asimo.nLegs
2
>>> asimo.nArms
2


객체의 필드를 확인하고 싶다면 내장 함수 vars()를 이용하면 된다.


>>> vars(asimo)
{'nLegs': 2, 'nArms': 2}


이 내장 함수는 사실 객체의 __dict__ 내부 필드를 반환한다. 이 내부 필드에 객체의 필드들이 딕셔너리의 요소로 저장되어 있다.


객체를 생성할 때 이름을 사용자가 입력하도록 하려면 다음과 같이 __init__() 메소드에 일반 인자를 self 뒤에 주면 된다.


class Robot:
   def __init__(self, name):
       self.nLegs = 2
       self.nArms = 2
       self.name = name


이제 객체를 생성할 때 이름을 반드시 입력해야 한다.


>>> asimo=Robot('asimo')
>>> asimo.name
'asimo'


만약 이름이 주어지지 않았을 때 ‘dummy’ 라는 이름을 주고 싶다면 다음과 같이 기본값 인자를 사용하면 된다.


class Robot:
   def __init__(self, name=’dummy’):
       self.nLegs = 2
       self.nArms = 2
       self.name = name

    

이제 객체를 생성할 때 이름을 입력하지 않아도 된다.


>>> asimo=Robot()

>>> asimo.name

'dummy'


이와 같이 __init__() 생성자 함수도 파이썬의 일반 함수처럼 가변 개수 인자, 기본값 인자, 키워드 인자 등을 적용할 수 있다.



Posted by 살레시오
,