Elements = [3, 4, 5]
For element in elements:
Print(element)
위 예시를 설명하자면,
iter(elements)
를 호출하여 (해당 iterable의 __iter__()
메서드를 호출하여) iterator을 가져온 후, iterable 객체
__iter__()
메서드를 작성해야 한다.__iter__()
메서드iterator
__iter__ 메서드
를 실행한 return 값iterator_object.__next__()
method를 사용하여 다음 element를 가져온다.__next()__
메서드를 구현해야 한다.내장 함수 iter()
내장 함수 next()
My_list = [1, 2, 3]
It = iter(my_list)
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
Traceback ~~~
StopIteration
__iter__()
메서드에서 self 를 return 함으로써 iterable 과 동일한 클래스에 iterator을 구현하였음을 표시Class MyCollection:
Def __init__(self):
Self.size = 10
Self.data = list(range(self.size))
Def __iter__(self):
Self.index = 0
Return self
Def __next__(self):
If self.index >= self.size:
Raise StopIteration
N = self.data[self.index]
Self.index += 1
Return N
Coll.= Mycollection()
For x in coll:
Print(x)
generator 함수
를 변수에 할당하면, 그 변수는 generator 클래스 객체가 된다.# generator 함수
def gen():
yield 1
yield 2
yield 3
# generator 클래스 객체
g_class = gen()
print(type(g_class)) # <class ‘generator’>
# next () 함수 이용
n = next(g_class); # 1
n = next(g_class); # 2
# for 루프 이용 가능
for x in gen():
print(x)
close()
메서드를 통해 종료되는 경우close()
메서드는 제너레이터를 명시적으로 종료시키고자 할 때 사용GeneratorExit
예외가 발생하며, 이를 통해 제너레이터가 자원을 해제하거나 필요한 종료 처리를 수행할 수 있음파일이나 네트워크 연결과 같은 외부 자원을 사용하고 있을 때
, close()
메서드를 호출하여 자원을 명시적으로 해제할 수 있음close()
메서드를 사용할 수 있습니다.close()
메서드를 호출하여 GeneratorExit
예외를 발생시키고 이를 처리함으로써 제너레이터의 실행을 안전하게 종료시킬 수 있습니다.def my_generator():
try:
yield 'Hello'
yield 'World'
except GeneratorExit:
# 제너레이터 종료 시 필요한 정리 작업
print('Generator is closing')
gen = my_generator()
print(next(gen)) # Hello 출력
print(next(gen)) # World 출력
gen.close() # Generator is closing 출력
yield가 포함된 함수
를 호출하기g = (n**2 for n in range(1001) ) # generator 객체 생성
for i in range(5):
value = next(g)
print(value)
1, 4, 9, 16, 25
for x in g:
print(x)
36, 49, ..
__iter__
메서드를 generator로 정의하면, 쉽게 iterable container type을 정의할 수 있다.class ReadVisits:
def __init__(self, data_path):
self.data_path = data_path
def __iter__(self):
with open(self.data_path) as f:
for line in f:
yield int(line)
visits = ReadVisits(path)
for line in visits:
print(line)
if isinstance(값, Iterator)
로 확인하라.def normalize_defensive(numbers):
if iter(numbers) is numbers: # 이터레이터 -- 나쁨!
raise TypeError('컨테이너를 제공해야 합니다')
if isinstance(numbers, Iterator): # 반복 가능한 이터레이터인지 검사하는 다른 방법
raise TypeError('컨테이너를 제공해야 합니다')
total = sum(numbers)
result = []
...
return result
def move(period, speed):
for _ in range(period):
yield speed
def animate():
for delta in move(4, 5.0):
yield delta
for delta in pause(3):
yield delta
for delta in move(2, 3.0):
yield delta
def animate_composed():
yield from move(4, 5.0)
yield from pause(3)
yield from move(2, 3.0)
def run_cascading():
amplitudes = [7, 7, 7, 2, 2, 2, 2, 10, 10, 10, 10, 10]
it = complex_wave_cascading(iter(amplitudes))
for amplitude in amplitudes:
output = next(it)
transmit(output)
run_cascading()
def complex_wave_cascading(amplitude_it):
yield from wave_cascading(amplitude_it, 3)
yield from wave_cascading(amplitude_it, 4)
yield from wave_cascading(amplitude_it, 5)
def wave_cascading(amplitude_it, steps):
step_size = 2 * math.pi / steps
for step in range(steps):
radians = step * step_size
fraction = math.sin(radians)
amplitude = next(amplitude_it) # 다음 입력 받기
output = amplitude * fraction
yield output
__iter__
메서드를 구현하는 클래스를 사용하면서 예외적인 경우에 상태를 transition 하는 것이다.
def run():
timer = Timer(4)
for current in timer:
if check_for_reset():
timer.reset()
announce(current)
run()
#
class Timer:
def __init__(self, period):
self.current = period
self.period = period
def reset(self):
self.current = self.period
def __iter__(self):
while self.current:
self.current -= 1
yield self.current
#
RESETS = [
False, False, False, True, False, True, False,
False, False, False, False, False, False, False]
def check_for_reset():
# 외부 이벤트를 폴링한다
return RESETS.pop(0)
>
3틱 남음
2틱 남음
1틱 남음
3틱 남음
2틱 남음
3틱 남음
2틱 남음
1틱 남음
0틱 남음
import itertools
it = itertools.chain([1, 2, 3], [4, 5, 6])
print(list(it))
it = itertools.repeat('안녕', 3) # 3은 최대 반복 횟수
print(list(it))
it = itertools.cycle([1, 2])
result = [next(it) for _ in range (10)]
print(result)
>
1, 2, 1, 2, 1, 2, 1, 2, 1, 2
it1, it2, it3 = itertools.tee(['하나', '둘'], 3)
print(list(it1))
print(list(it2))
print(list(it3))
keys = ['하나', '둘', '셋']
values = [1, 2]
normal = list(zip(keys, values))
print('zip:', normal)
it = itertools.zip_longest(keys, values, fillvalue='없음')
# fillvalue 의 default는 None이다.
longest = list(it)
print('zip_longest:', longest)
>
(‘하나’, 1)
(‘둘‘, 2)
(‘셋’, ‘없음’)
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
first_five = itertools.islice(values, 5)
print('앞에서 다섯 개:', list(first_five))
>
[1, 2, 3, 4, 5]
middle_odds = itertools.islice(values, 2, 8, 2)
print('중간의 홀수들:', list(middle_odds))
>
[3, 5, 7]
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
less_than_seven = lambda x: x < 7
it = itertools.takewhile(less_than_seven, values)
print(list(it))
>>>
[1, 2, 3, 4, 5, 6]
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
less_than_seven = lambda x: x < 7
it = itertools.dropwhile(less_than_seven, values)
print(list(it))
>>>
[7, 8, 9 ,10]
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = lambda x: x % 2 == 0
filter_result = filter(evens, values)
print('Filter:', list(filter_result))
>>>
Filter: [2, 4, 6, 8, 10]
filter_false_result = itertools.filterfalse(evens, values)
print('Filter false:', list(filter_false_result))
>>>
Filter false: [1, 3, 5, 7, 9]
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum_reduce = itertools.accumulate(values)
print('합계:', list(sum_reduce))
>>>
합계: [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
def sum_modulo_20(first, second):
output = first + second
return output % 20
modulo_reduce = itertools.accumulate(values, sum_modulo_20)
print('20으로 나눈 나머지의 합계:', list(modulo_reduce))
>>>
20으로 나눈 나머지의 합계: [ 1, 3, 6, 10, 15, 1, 8, 16, 5, 15]
single = itertools.product([1, 2], repeat=2)
print('리스트 한 개:', list(single))
>>>
리스트 한 개: [(1, 1), (1, 2), (2, 1), (2, 2)]
multiple = itertools.product([1, 2], ['a', 'b'])
print('리스트 두 개:', list(multiple))
리스트 두 개: [(1, ‘a’), (1, ‘b’), (2, ‘a’), (2, ‘b’)]
it = itertools.permutations([1, 2, 3, 4], 2)
print(list(it))
>>>
[(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4,1), (4, 2), (4, 3)]
it = itertools.combinations([1, 2, 3, 4], 2)
print(list(it))
>>>
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
it = itertools.combinations_with_replacement([1, 2, 3, 4], 2)
print(list(it))
>>>
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 4)]