ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python - 함수에 배열을 인자로 전달할 때
    Python 2020. 12. 23. 17:35

    함수에 배열을 전달할 때 무슨 일이 일어날까?

     

    함수의 인자로 배열을 전달한 후에 배열에 5를 'append' 해보자.

     

    def append_item(arr_in_function):
        print('id : ', id(arr_in_function), 'before change in function : ',arr_in_function)
        arr.append(5)
        print('id : ', id(arr_in_function), 'after change in function : ',arr_in_function)
    
    arr = [1,2,3,4]
    print('id : ', id(arr), 'before function : ', arr)
    append_item(arr)
    print('id : ', id(arr), 'after function : ', arr)

     

    append_item이라는 함수에 인자로 arr라는 배열을 넘겼다.

    함수 내에서는 arr_in_function에 5를 추가하는 과정을 거친다.

    • 함수에 리스트를 전달하기 전
    • 리스트가 함수에 전달된 후
    • 함수 내에서 리스트에 5를 추가한 후
    • 함수가 종료된 이후

     

    각각의 상황에서 arr의 id를 조회해보면, 아래와 같이 id 값이 모두 동일하다는 것을 알 수 있다. 또한, 함수가 종료된 이후에도 arr에는 5가 여전히 추가되어 있다.

    따라서, 함수에 배열을 전달하더라도, 배열을 구성하는 요소들이 모두 복사되어 전달되는 것이 아니라 배열의 값들을 가리키는 주소만 전달된 다는 것을 알 수 있다.

     

     

     

    함수에 arr라는 배열을 가리키는 변수를 전달했을 때 함수 내에서 arr_in_function이라는 변수도 동일한 id값을 가리키게 된다.

    함수 내에서 arr_in_function이 가리키는 배열에 5를 추가했다. 때문에, 함수가 종료되고 arr_in_function이라는 변수가 사라져도 arr는 여전히 5가 추가된 동일한 배열을 가리키고 있는 것이다.

     

     

    함수의 인자로 배열을 전달한 후에 새로운 배열로 바꿔보자.

     

    def append_item(arr_in_function):
        print('id : ', id(arr_in_function), 'before change in function : ', arr_in_function)
        arr_in_function = [10, 11, 12]
        print('id : ', id(arr_in_function), 'after change in function : ', arr_in_function)
    
    arr = [1,2,3,4]
    print('id : ', id(arr), 'before function : ', arr)
    append_item(arr)
    print('id : ', id(arr), 'after function : ', arr)

     

    append_item이라는 함수에 인자로 arr라는 배열을 넘겼다.

    함수 내에서는 arr_in_function에 새로운 배열을 할당해 주었다.

     

    그 결과 이번에는 새로운 배열이 할당된 이후, arr_in_function의 id값이 변경되었으며, arr는 함수가 종료된 이후에도 변하지 않았다.(3번째 줄에서 id가 바뀌었고, 4번째 줄에서는 arr의 값이 그대로 남아있음을 확인할 수 있다.)

     

     

     

    첫 번째 상황과 어떤 점이 달라진 것일까?

     

    함수의 인자로 전달된 arr에 5라는 원소를 추가할 때는 arr와 arr_in_function이 동일한 주소를 가리키고, 그 주소가 가리키는 배열의 끝에 5가 추가되었다.

     

    하지만, 이번에는 함수 내에서 arr_in_function에 새로운 배열을 넣어주었다. 따라서, arr_in_function은 이제 다른 배열을 가리키게 되었다. 이제 두 변수가 가리키는 주소가 달라졌기 때문에, arr_in_function을 아무리 변경해도 함수 밖의 arr에 영향을 끼치지 못한다.

     

    reference - stack overflow link


     

     

    추가 실험

     

    여기까지가 Stack overflow에서 참고한 내용이다. 그렇다면, 배열을 arr[1:]과 같이 잘라서 함수에 전달한다면 어떻게 될까?

    궁금해져서 직접 한번 실험해 보았다.

     

    먼저 배열에 arr[1:]을 전달하고 숫자 5를 append해보았다.

     

     

    def append_item(arr_in_function):
        print('id : ', id(arr_in_function), 'before change in function : ', arr_in_function)
        arr_in_function.append(5)
        print('id : ', id(arr_in_function), 'after change in function : ', arr_in_function)
    
    arr = [1,2,3,4]
    print('id of arr ',id(arr))
    for i in range(len(arr)):
        print(f'id of arr[{i}:]',id(arr[i:]))
    
    print()
    
    print('id : ', id(arr), 'arr before function : ', arr)
    append_item(arr[1:])
    print('id : ', id(arr[1:]), 'arr[1:] after function : ', arr[1:])
    print('id : ', id(arr), 'arr after function : ', arr)
    
    print()
    
    for i in range(len(arr)):
        print(f'id of arr[{i}]',id(arr[i]))

     

    아래와 같이 잘라서 함수에 전달하고, 5를 append했을 때, 짐작대로 arr는 변하지 않았다.

    하지만, 여기서 특이한 점을 발견할 수 있었다.

     

    1. 첫 번재 네모 박스 내의 id값이 모두 동일하다.

     

    2. 함수 내의 arr_in_function과 함수 외부의 arr[1:]의 id가 동일하다. 그런데 함수 내부의 arr_in_function의 변경사항이 arr[1:]에는 반영되지 않는다.

     

     

    id()

     

    • Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

    1번, 2번의 의문점을 해결해보자...

    'Python' 카테고리의 다른 글

    cPython [Deep Dive to Object] - 1  (0) 2021.04.21
    Python - Variable Scope  (0) 2021.01.06
    Python - Call by Object Reference  (1) 2020.12.26
    Python?  (0) 2020.12.21
Designed by Tistory.