728x90

 


목차

1. 아이터레이터(Iterator)
2. 리스트 컴프리헨션(comprehension)
3. 람다(lambda)
4. map
5. filter


1. 아이터레이터(lterator)

 

iter함수가 반환하는 객체를 iterator객체라고 하고 iterator객체를 얻을 수 있는 자료형을 iterable타입이라고 한다. 대표적인 iterable타입으로는 리스트, 딕셔너리, 튜플, 문자열 등이 있다.
iterator객체를 이루고 있는 인자는 next함수를 사용해 하나씩 꺼낼 수 있는데 이는 마치 리모컨(next)을 누르면 자판기(iterator)에서 사탕이 하나씩 떨어지는 원리와 유사하다.
자판기에서 사탕이 떨어지면 경고문구가 나오듯 iterator객체 내부 인자를 모두 꺼낸 상황에서 추가적으로 next함수를 호출한다면 StopIteration예외가 발생한다. 추가적으로 for루프의 반복 대상은 반드시 iterator객체어어야 한다.

iterator를 정리하면서 어디다 쓸 수 있을 지 생각해봤는데, 게임 만들 때 캐릭터 목숨 수에 사용하면 될 거 같다. 그래서 아래에 한번 iterator를 이용해서 플레이어 게임 횟수를 구현해 보았다.

player_count = [5, 4, 3, 2, 1, "Game Over"]
ir_player = iter(player_count) # iter()함수를 사용해 iterator객체(ir_player)를 얻음

# 플레이어가 몬스터에 닿을 때마다 hit함수가 출력됨
def hit():
    print(next(ir_player))


hit()   #5
hit()   #4
hit()   #3
hit()   #2
hit()   #1
hit()   #Game Over

2. 리스트 컴프리헨션(Comprehension)

 

리스트 객체에 여러 인자가 있는데 인자를 하나씩 꺼내려면 for루프를 사용하게 된다.
이런 상황에서 for루프나 if문을 리스트 안으로 넣음으로써 간결하고 명확한 코드를 작성할 수 있다.

* 리스트 컴프리헨션을 잘 쓰는 것만으로도 map 함수와 filter함수를 대신 할 수 있다.

#구구단을 홀수단만 출력하는 상황

#1) for루프와 if문으로 구현
gugudan_list = list(range(2, 10))
even_gugudan = []

for x in gugudan_list:
    for y in range(1, 10):
        if x%2 != 0:
            even_gugudan.append(x*y)
print(even_gugudan)


#2) 리스트 컴프리헨션으로 구현
gugudan_comprehension = [n*m for n in range(2, 10) for m in range(1, 10) if n % 2]
print(gugudan_comprehension)

# 1)과 2)는 결과적으로 같지만 2)코드가 훨씬 간결하다

 


3. 람다(lambda)

 

함수 안에 함수를 만들어 반환하는 경우에는 구조적으로 복잡해지게 된다. 이때 필요한게 '람다'라는 개념이다. 람다는 객체 안에서 함수 정의가 가능하기 때문에 코드가 간결해지게 된다.
람다식에서 함수를 호출하는 것이 가능하고, 매개변수가 없을 수 있고 둘 이상 받을 수도 있다.(이때는 매개변수를 콤마(,)로 구분)

* 람다식에는 return이 있는 것으로 생각하며, return을 사용하면 오류가 발생한다.
* 람다식이 True/False를 반환할 때, 몸체 부분에 not( )을 사용하면 반환하는 값을 바꿀 수 있다.
ex) list(filter(lambda n: not(n%2), st))

# 함수 내부에서 람다식 사용
def test(n):
    return lambda x:x**n


f2 = test(2)    # lambda x:x**2
print(f2(4))   # lambda 4:4**2

# 람다식에서 len(x)함수를 사용함
lambda_in_func = lambda x: len(x)
print(lambda_in_func("test"))

4. map

 

map(func, obj) 구조를 갖는 기본 함수로 obj에 저장된 값들을 하나씩 전달하면서(이때, obj는 iterable 객체) func함수를 호출한다. 결과적으로 obj에 저장된 값의 수만큼 func함수가 호출된다. 연산이 끝나면 map은 하나의 객체를 반환하는데 이 객체는 iterator객체다.

* map함수는 최소 2개 이상의 인자가 있어야 함
* map함수 내에서 람다식을 사용할 수 있음

def test(n):
    return "hello_"+n


itr_obj = ["user1", "user2", "user3", "user4"]
print(tuple((map(test, itr_obj)))) #('hello_user1', 'hello_user2', 'hello_user3', 'hello_user4')


# map 안 함수에 두개 이상의 iterator객체 전달
def sum(n1, n2):
    return n1+n2


ob1 = [1, 2, 3]
ob2 = [3, 2, 1]
print(list(map(sum, ob1, ob2))) #[4, 4, 4]

# map안에 람다식 사용
st = ['one', 'two', 'three']
rst = list(map(lambda s: s[::-1], st))
print(rst)

5. filter

 

filter(func, obj) 구조를 갖는 기본 함수로 map함수와 기본 골격은 같다. filter 함수의 첫번째 인자 func는 True/False를 반환하는 함수, 두번째 인자 obj는 iterable 객체여야 한다. 두번째 인자 obj에서 저장된 값이 func로 전달되고 func연산 결과 True라면 값을 반환하고 False라면 값을 걸러내는 일종의 필터 기능을 함

st = list(range(1, 11))
fst = list(filter(lambda n: not(n % 3), map(lambda n: n**2, st)))

print(fst)

 

728x90

+ Recent posts