4. 함축(컴프리헨션), 함수

2016. 10. 14. 21:51Programming Languages/PYTHON

5)컴프리헨션(Comprehension)
컴프리헨션(함축)은 하나 이상의 이터레이터로 부터 자료구조를 만들 때 번거로움을 줄여주는 기능이다.
리스트, 딕셔너리, 셋, 제너레이터를 컴프리헨션으로 생성할 수 있다. 튜플은 불가능하다!

리스트의 컴프리헨션은 아래 예제에서 확인 가능하듯이 
[표현식 for 항목 in 순회 가능한 객체 if 조건] 의 형식으로 사용가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
number_list=[number for number in range(1,6)]
print(number_list)
 
[1,2,3,4,5]
 
#튜플 언패킹으로 두개 이상의 for 절을 사용하는 것이 가능하다.
cells=[(row,col) for row in range(1,2for col in range(3,5)]
for cell in cells:
    print(cell)
 
(1,3)
(1,4)
 
#for 절 뒤에 if 로 조건을 붙이는 것도 가능.
sample_list=[number for number in range(2,7), if number%3==0]
print(sample_list)
 
[3,6]
cs


딕셔너리의 컴프리헨션도 아래 예제에서 확인 가능하듯이

[키 표현식: 값 표현식 for 항목 in 순회 가능한 객체] 의 형식으로 사용할 수 있고 리스트와 마찬가지로 if나 여러개의 for 가 허용된다.

1
2
3
4
5
word='letters'
letter_counts={letter:word.count(letter) for letter in word}
letter_counts
 
{'l':1,'e':2,'t':2,'r':1,'s':1}
cs


튜플은 컴프리헨션을 사용할 수 없으며, 만약 {}나 []대신 ()를 이용해서 리스트나 딕셔너리의 컴프리헨션과 비슷하게 튜플의 컴프리헨션을 사용하려고 한다면 전혀 다른 결과를 얻게 될 것이다. 

()를 사용해서 할 수 있는 것은 제너레이터 컴프리헨션인데, 제너레이터는 for와 같은 이터레이터에 데이터를 제공하는 방법 중 하나로 순회 가능한 객체이다. 주의할 점은 제너레이터는 자신의 값을 기억하지 않으므로 생성 직후 한 번만 실행될 수 있어서 재사용이 불가능하다.



6)함수

파이썬의 함수에서 가장 인상 깊었던건 들여쓰기로 완성하는 코드 구조였다. C에서 {}로 함수를 열고 닫는 것과 다르게 파이썬은 들여쓰기가 그 역할을 수행한다.



함수 내에서 for나 if등 지금까지 배운 코드구조를 활용하는 것도 가능하고 

1
2
3
def print_1_to_5():
    for number in range(1,6):
        print(number)
cs



인자를 받아들여서 특정 값을 리턴하는 것도 가능하다. 사용자가 인자를 넣지 않았을때 기본 값을 사용할 수도 있다. (아래 코드의 경우 agree의 디폴드 값이 True이다.)

1
2
3
4
5
def decide(agree=True):
    if(agree):
        return 'YES'
    else:
        return 'NO'
cs



* 함수에서 인자를 받아들이는 방법으로 크게 두 가지가 있다. 다른 언어에서 기본적으로 사용되는 위치 인자는 함수를 정의할 때 지정해둔 위치에 해당 변수를 넣어서 값을 처리하는 방법이다. 하지만 위치인자로 값을 넘겨주기 위해서는 어느 위치에 어떤 값을 넣어야하는지 알고 있어야 한다. 

반면 키워드 인자는 함수를 정의할 때 썼던 인자명을 알고 있다면 위치에 상관 없이 그 값을 넘겨줄 수 있다. 

키워드 인자와 위치 인자는 동시에 사용될 수 있지만 반드시 위치인자를 먼저 써주어야한다.

1
2
3
4
5
6
7
8
def relationship(owner, petkind, petname):
    print(owner, "raises a", petkind,"named",petname)
 
relationship('Sam','cat','Lucy')
 
Sam raises a cat named Lucy
 
relationship('Tom',petname='Jack',petkind='dog')
cs



사용자가 지정한 인자보다 더 많은 개수의 위치인자를 입력한 경우도 쉽게 처리할 수 있다. 이때 *은 포인터라는 뜻이 아니며, 가변 인자를 사용하겠다는 뜻이다. 관용적으로 args라는 이름을 많이 사용한다.

1
2
3
def print_name(*args):
    for name in args:
        print(name)
cs



**로 키워드 인자를 딕셔너리로 받아들일 수 도 있다. *와 마찬가지로 포인터가 아니며, 인자의 개수도 가변적이다.

1
2
3
4
5
6
7
8
def print_nick_name(**kwargs):
    for nick in kwargs:
        print(kwargs[nick],"'s nickname is",nick)
 
print_nick_name(toto='tom',wef='sally')
 
toms 's nickname is toto
sally 's nickname is wef
cs



파이썬에서는 help() 함수를 제공한다. 원하는 함수의 이름을 인자로 넣으면 그 함수에 대한 설명을 보여주기 위함이다.

사용자 정의 함수에서도 help로 읽어들일 수 있는 설명문을 붙일 수 있다. 이것을 docstring이라고 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def sample(argument):
    '''
    This function is sample.
    If you want to get some information about this function,
    please type help(sample).
    '''
    print (argument)
 
help(sample)
 
Help on function sample in module __main__:
 
sample(argument)
    This fuction is sample.
    If you want to get some information about this function,
    please use help(sample).
cs



파이썬에서는 함수도 객체로 다루어질 수 있다. 따라서 함수에서 함수를 인자로 받아들이는 것이 가능하다. 또한, 예로 들지는 않았지만 파이썬에서는 어떤 함수를 정의할 때 그 안에 새로운 함수를 정의하는 것도 가능하다. 

1
2
3
4
5
6
7
8
9
def run_func(func):
    func()
 
def say_hello():
    print("Hello!")
 
run_func(say_hello)
 
Hello!
cs