본문 바로가기
Python 파이썬/기초 & 내장모듈

python ) 이터레이터와 제너레이터, 참조

by 하이방가루 2022. 3. 8.
728x90
반응형

이터러블 (iterable ; 반복할 수 있는 것)

  내부에 있는 요소들을 차례차례 꺼낼 수 있는 객체

 

이터레이터( iterator )

  이터러블 중에서 next()함수를 적용해 하나하나 꺼낼 수 있는 요소

  메모리 주소를 저장한다.

  C언어 포인트?

  print()함수로 이터레이터를 출력하면 자신의 메모리 주소를 출력한다. 저장된 메모리 주소가 아니다.

 

yield 키워드 ( 제너레이터 ; generator )

  이터레이터를 직접 만들 때 사용하는 코드

  next()함수를 사용해 함수 내부의 코드를 실행할 때, yield 키워드 부분까지만 실행하며 그 뒤에 메모리 주소를 반환한다.

  next()함수를 호출한 이후 yield 키워드를 만나지 못하고 함수가 끝나면 StopIteration이라는 예외가 발생한다.

 

제너레이터 함수

  이터레이터를 반환하는 함수

numbers = [1, 2, 3]
r_num = reversed(numbers)

print( r_num ) # <list_reverseiterator object at 메모리주소>
print( next( r_num ) ) # 3
print( next( r_num ) ) # 2
print( next( r_num ) ) # 1
print( next( r_num ) ) # StopIteration

 

참조 ( reference )

  보통 메모리의 주소를 뜻하며 참조변수란 어떠한 객체의 메모리 주소를 갖고있는 변수로 객체를 가리키고 있는 것을 말한다.

  list, dict는 모두 참조변수로 실제 값이 아닌 리스트 객체나 딕셔너리 객체를 가리키는 메모리 주소를 가지고 이들을 찾아 값을 가져온다.

 

얕은 복사 ( Shallow copy )

  list, dict 등 참조변수가 들어있는 변수를 다른 변수에 할당할 경우 같은 객체를 가키고 같은 객체를 수정하게 된다.

  그렇기 때문에 다음과 같은 문제가 발생한다.

list_a = [1,2,3,4,5]
list_b = list_a
list_b[0] = 10

print( list_b ) # [10,2,3,4,5]
print( list_a ) # [10,2,3,4,5]

list_a를 할당받은 list_b의 객체를 수정했는데 list_a의 객체도 같이 수정된다. 이는 객체의 주소를 할당했기 때문에 발생한다.

 

깊은 복사 ( Deep copy )

  깊은 복사란 변수를 할당할 때 객체 주소가 아닌 객체의 실제 값을 복사하는 것을 뜻한다.

list_a = [1,2,3,4,5]
list_b = list_a.copy()
list_b[0] = 10

print( list_b ) # [10,2,3,4,5]
print( list_a ) # [1,2,3,4,5]

하지만..... 이것도 중첩된 객체에서는 불가능하다....

list_a = [[1,2,3],[4,5,6]]
list_b = list_a.copy()
list_b[0][0] = 10

print(list_b) # [[10, 2, 3], [4, 5, 6]]
print(list_a) # [[10, 2, 3], [4, 5, 6]]

이런 경우 내부 변수를 판별하여 다시 값을 할당해줘야한다.

def deep_copy(value):
  if type(value) is list:
    output = []
    for v in value:
      output.append(deep_copy(v))
    return output
#  elif type(value) is dict:
#    output ={}
#    for k,v in value.items():
#      output[k] = deep_copy(v)
#    return output
  else:
    return value

list_a = [[1,2,3],[4,5,6]]
list_b = deep_copy(list_a)
list_b[0][0] = 10

print( list_b ) # [[10, 2, 3], [4, 5, 6]]
print( list_a ) # [[1, 2, 3], [4, 5, 6]]

 

is와 ==

  == 은 값이 같은지 다른지 판단한다

  is 는 같은 객체를 가리키고 있는지 판단한다.

728x90
반응형

댓글