Python

iterators

traveler_JH 2022. 7. 6. 23:23

ioterators 는 값을 순차적으로 꺼내올수 있는 객체이다

기존에 우리는 리스트 안에서 값을 빼오기 위해 for 문을 이용했다.

만약 리스트안에 있는 값을 제곱 해서 반환 하는 코드를 보자

L = [1,2,3]

#기존
for x in L:
	print(x**2,end=' ')

이런식으로 사용 했었다.

만약 여기서 L이 리스트라고 명시 되지 않고 변수명만 주어졌다고 한다면 우리는 과연 어떻게 L이 반복 가능한 객체인지 확인을 해봐야할까?

바로 dir 을 확인 하는것이다.

이런식으로 프린트를 찍어본다면

['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', 
'__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', 
'__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', 
'__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
 '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 
'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 
'reverse', 'sort']
  • 이렇게 많은 속성이 나온다 dir의 기능은 어떠한 객체를 인자로 넣어주면 해당 객체가 어떤 변수와 메소드(method)를 가지고 잇는지 나열해준다.

위의 변수와 메소드를 보다보면 iter 함수가 들어있는것을 확인할수있다.

그렇다면 __iter__를 출력 해보자

print(L.__iter__)

#<method-wrapper '__iter__' of list object at 0x102ef3300>

`부분을 보면 우리는 iter를 통해 L이 list 오브젝트인것을 알았다.

음 그렇다면 iter 가 함수로 선언 되어있는곳을 가보자

어...? iter(self)로 구현을 했다고 한다.

그렇다면 iter(L)은??

print(iter(L))
#<list_iterator object at 0x1034326e0>

간결 하게 리스트 라는것을 알려줌과 동시에 메모리 주소를 반환해준다.

이제 L이 리스트인것을 알았으니 요소를 하니씩 꺼내오려면

dir중에 __next__라는 메서드가 눈에 띄인다.

new_L = iter(L)
print(L.__next__())
# 1

한번에 하나씩 빠져나온다.

new_L = iter(L)
print(L.__next__())
print(L.__next__())
print(L.__next__())
# 1
#	2
# 3

만약 더이상 가져올 값이 없다면 StopIteration 이 발생한다.

동일하게 next 는 그렇다면 next가 없을까?

찾아보니 이런식으로 next() 가 지정되어있었다.

위의 두개를 이용하여 리스트안에 있는 값을 제곱 해서 반환 하는 코드를 만들어 보자

L = [1,2,3]

I = iter(L)
while True:
	try:
		result = next(I)
	except Exception :
		break
	print(result**2, end= " ")

#1 4 9

속도 비교

import timeit

test_li = list(range(1, 1001))
def none_iter():
    for res in test_li:
        return res

def use_iter():
    I = iter(test_li)
    while True:
        try:
            result = next(I)
        except Exception:
            break
        return result

if __name__ == "__main__":
    time_01 = timeit.Timer("none_iter()", "from __main__ import none_iter")
    time_02 = timeit.Timer("use_iter()", "from __main__ import use_iter")
    print("none_iter time", time_01.timeit(number=1000), 'milliseconds')
    print("use_iter  time", time_02.timeit(number=1000), 'milliseconds')

#none_iter time 8.058396633714437e-05 milliseconds
#use_iter  time 0.00012266600970178843 milliseconds

 

'Python' 카테고리의 다른 글

정규표현식  (0) 2022.07.06
객체(Object)  (0) 2022.07.06
list comprehensions  (0) 2022.07.06
if문을 많이 쓰면 안좋은 이유  (0) 2022.07.06
함수  (0) 2022.07.05