Iterable

장현빈·2024년 11월 27일

python

목록 보기
5/8

iterable이란 파이썬에서 반복문을 사용할 수 있는 객체를 의미한다.

  • 어떤 객체가 iterable한지 알수 있는 방법: iter()에 인자 전달
a=1
print(iter(a)) # iterable 하지 않음
a=1

for i in a: # 에러 발생
    print(i)
a=[1,2,3]
print(iter(a)) # 출력 결과 <list_iterator object at 0x1047de6b0>
a=[1,2,3]

for i in a:
    print(i)

출력결과

1
2
3

Iterator 객체

순회할 수 있는 객체를 의미. 파이썬에서 이터레이터는 iter()와 next() 메서드를 구현한 객체를 의미.

# 예제 코드
class MyIterator:
    def __next__(self):
        return 1
    
class MyIterable:
    def __iter__(self):
        obj=MyIterator()
        return obj
    
m=MyIterable()
r=iter(m)
print(next(r))
print(next(r))
print(next(r))

구현 방법

  • 이터러블 객체 만들기
class Season:
    pass

s=Season()
for i in s:
    print(i)
  • __iter__ method 구현
class Season:
    def __init__(self):
        pass
    def __iter__(self):
        return self

s=Season()
for i in s:
    print(i)
  • __next__ method 구현
class Season:
    def __init__(self):
        self.data=["봄", "여름", "가을", "겨울"]
        self.index=0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index<len(self.data):
            cur_season=self.data[self.index]
            self.index+=1
            return  cur_season
        else:
            raise StopIteration

s=Season()
for i in s:
    print(i)

map()과 filter()

map함수는 반복가능한 iterable 객체를 받아서, 각 요소에 함수를 적용하주는 함수

# 기존 코드

def add_1(n):
    return n+1

target=[1,2,3,4,5]
result=[]
for value in target:
    result.append(add_1(value))
    
print(result) # 결과 [2, 3, 4, 5, 6]
  • map함수를 이용하면 위와 같은 연산을 더 쉽게, 메모리도 절약할수 있는 iterator를 결규ㅏ를 받을수 있음.
# map 함수 적용

def add_1(n):
    return n+1

target=[1,2,3,4,5]
result=map(add_1, target)
    
print(list(result)) # 결과 [2, 3, 4, 5, 6]
# lambda 함수 적용

target=[1,2,3,4,5]

result=map(lambda x: x+1, target)
print(list(result)) # 결과 [2, 3, 4, 5, 6]

리스트 안의 값들을 str 타입으로 변환하는 예제

target=[1,2,3,4,5]
map(str, target)

filter함수는 특정 조건으로 걸러서 걸러진 요소들로 iterator 객체를 만들어서 리턴

# 기존 코드
target=[1,2,3,4,5,6,7,8,9,10]
result=[]

def is_even(n):
    return True if n%2==0 else False

for value in target:
    if is_even(value):
        result.append(value)
        
print(result) # 결과 [2, 4, 6, 8, 10]
# filter() 적용
target=[1,2,3,4,5,6,7,8,9,10]

def is_even(n):
    return True if n%2==0 else False

result=filter(is_even, target)

print(list(result)) # 결과 [2, 4, 6, 8, 10]
# lambda 적용
target=[1,2,3,4,5,6,7,8,9,10]
result=filter(lambda x: x%2==0, target)
print(list(result)) # 결과 [2, 4, 6, 8, 10]

제너레이터

이터레이터를 더 간단하게 구현할 수 있는 방법. 제너레이터는 함수 내에서 yield 키워드를 사용하여 값들을 하나씩 반환. 이터레이터와 마찬가지로 순회할 수 있는 객체를 반환.

# 예제 코드
def num_gen():
    for i in range(3):
        yield i
        
g=num_gen()

num1=next(g)
num2=next(g)
num3=next(g)

print(num1, num2, num3) # 결과 0 1 2
# for와 같이 사용
def num_gen():
    for i in range(3):
        yield i+1
        
g=num_gen()

for i in g:
    print(i)

실행 결과

1
2
3

데코레이터

기존의 함수를 수정하지 않고, 그 함수에 기능을 추가하거나 수정하는 방법. 데코레이터는 함수나 메서드를 인수로 받아서 새로운 함수를 반환하는 함수.

# 예제 코드

def my_decorator(func):
    def wrapper():
        print('before func')
        func()
        print('after func')
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")
    
say_hello()

출력 결과

before func
Hello!
after func
def hello():
    print("hello")
>>> hello()
hello
def deco(fn):
    def deco_hello():
        print("*"*20)
        fn()
        print("*"*20)
    return deco_hello
    
deco_hello=deco(hello)

hello() # 결과 hello
deco_hello()
********************
hello
********************
# @기호 사용하기

@deco
def hello2():
    print("hello 2")
    
hello2()
********************
hello 2
********************
  • 데코레이터 사용 예시
class Car:
    def __init__(self, model):
        self.model=model
    
    @property
    def get_model(self):
        return self.model
    
c=Car("GV80")
print(c.get_model)

Closure와 데코레이터

def outer(out1):
    def inner(in1):
        print("inner function called")
        print("outer argument: ", out1)
        print("inner argument: ", in1)
    return inner

f=outer(1)
f(10)
def outer(out1):
    def inner(in1):
        print("inner function called")
        print("inner argument: ", in1)
        out1()
    return inner

def hello():
    print("hello")
    
f=outer(hello)
f(10)

데코레이터 정리

def inner():
    print("inner function called")
    
inner()

데코레이터와 Closure의 차이점은 외부 함수의 인자로 어떤 함수 객체를 입력받는다는 점.

def deco(f):
    def wrapper():
        print("-"*20)
        f()
        print("-"*20)
    return wrapper
    
decorated_inner=deco(inner)
decorated_inner()
  • 데코레이터는 어떤 함수가 호출되기 전과 후에 추가적인 구현으로 함수의 기능에 변화를 주고 싶을때 사용.
  • 데코레이터를 사용하면 inner함수를 수정하지 않고도 기능 추가가 가능
@deco
def inner():
    print("inner function called")
    
inner()
profile
인공지능 관련 분야에 관심있습니다.

0개의 댓글