https://school.programmers.co.kr/learn/courses/30/lessons/43165

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

프로그래머스 '타겟넘버' 문제를 풀며, 제목과 같은 에러를 만났었습니다.

 

이에, 해당 문제를 해결할 수 있는 방법인 nonlocal과 global 변수 범위 지정 키워드에 대해서 정리하고자 합니다.

def solution(numbers, target):
    answer = 0
    length = len(numbers)

    def dfs(i, val):
        if val == target and i == length - 1:
            answer += 1
            return 0

        if i + 1 < length:
            dfs(i + 1, val + numbers[i + 1])
            dfs(i + 1, val - numbers[i + 1])

    dfs(-1, 0)
    return answer

 

처음에는 위와 같이 코드를 작성하였습니다. 

저는 solution 함수 내에 answer 변수가 선언 되어 있으므로, dfs 함수 내에서도 사용할 수 있을 것이라 생각하였습니다.

 

에러 코드를 보면 '할당되지 않아서' 에러가 발생함을 알 수 있습니다.

 

파이썬 컴파일러는 dfs 내의 answer 변수를 solution 함수 내의 answer 변수와 동일한 변수로 보지 않고, dfs 함수 내의 '로컬 변수'로 인식하여 발생하는 에러였습니다.

 

def solution(numbers, target):
    answer = 0
    length = len(numbers)
    visited = [False] * length

    def dfs(i, val):
        nonlocal answer
        
        if val == target and i == length - 1:
            answer += 1
            return 0

        if i + 1 < length:
            dfs(i + 1, val + numbers[i + 1])
            dfs(i + 1, val - numbers[i + 1])

    dfs(-1, 0)
    return answer

첫번째 해결 방법은 dfs 함수 내에 answer라는 변수에 nonlocal 이라는 keyword를 지정해주는 것입니다.

해당 키워드를 지정하게 되면, answer이라는 변수를 dfs 함수 내의 로컬 변수로 취급하지 않고 solution 함수 내의 answer 변수를 의미한다고 설정해주는 것입니다.

 

def solution(numbers, target):
    global answer
    answer = 0
    length = len(numbers)
    visited = [False] * length

    def dfs(i, val):
        global answer

        if val == target and i == length - 1:
            answer += 1
            return 0

        if i + 1 < length:
            dfs(i + 1, val + numbers[i + 1])
            dfs(i + 1, val - numbers[i + 1])

    dfs(-1, 0)
    return answer

두번째 해결 방법은 global이라는 keyword를 지정해주는 것입니다. 

global 변수는 해당 변수를 전역 변수로 사용하겠다는 것을 의미합니다.

따라서 위와 같이 각 함수 내에 global이라는 keyword를 사용하여 answer이라는 변수를 로컬 변수가 아닌 전역 변수로 설정해주는 방법이 있습니다.

안녕하세요.

오늘은 백준 알고리즘을 풀며 만났던 TypeError: cannot unpack non-iterable int object 에 대해 글을 써보려 합니다.

 

먼저, 해당 에러를 접한 상황은 다음과 같습니다. (백준 알고리즘 1916번, 18352번)

저는 deque에 (distance,node)의 값을 넣고, pop() 할 때마다 두 값을 한번에 얻고 싶었습니다. 다음과 같이 말이죠.

q = deque((distance,node))
newDistance , newNode = q.pop()

하지만, TypeError가 발생하여서 문제는 풀어야해서 항상 다음과 같이 풀었습니다.

q = deque()
q.append((distance,node))
newDistance , newNode = q.pop()
print(newDistance,newNode)

 

문제를 풀고 나서, 왜 그렇지 하고 여러가지 테스트를 해보았는데 역시나.. deque를 잘못사용하고 있었습니다.

테스트를 위해 아래와 같이 코드를 돌려보았습니다.

q = deque((0,99))
print(q)
q = deque([0,99])
print(q)
q = deque([(0,99)])
print(q)

 

그랬더니 위와 같은 결과 값이 나왔습니다. 여기서 아뿔사 했습니다..(역시 기본이 제일 중요하다는 것을 뼈저리게 느끼며...)

 

파이썬의 deque() 함수는 선언할 때 들어왔던 인자를 자동으로 deque화 시켜서 저장한다는 것을 놓쳤던 것입니다.

 

다음과 같이 사용하면, q[0]에 0이 q[1]에 99가 들어가는 것이죠.

print를 통해 출력해보면 이런 결과값이 나옵니다.

q = deque((0,99))
print(q[0],q[1])

q = deque([0,99])
print(q[0],q[1])

 

 

 

q = deque()
q.append((distance,node))
newDistance , newNode = q.pop()

***

(3번째줄) 이렇게 사용한다면, 입력받고자 하는 변수 갯수와 입력하고자 하는 변수 갯수가 맞지 않기 때문에 Error가 발생하는 것이었습니다.

 

'TypeError: cannot unpack non-iterable int object' -> ' iterable 하지 않은 int형 객체를 unpack 할 수 없다' Error 내용은

입력하고하 하는 변수 갯수는 1개인데, 입력받고자 하는 변수 갯수가 2개 여서 값을 할당할 수 없다라는 것입니다.

 

 

그렇다면 제가 의도한 방식대로 하려면 어떻게 했어야 할까요?

 

정답은 다음과 같이 [] 안에 다시 tuple형태로 감싸서 값을 담는 것입니다.

q = deque([(0,99)])

한번 값을 확인해보면 다음과 같이 나옴을 알 수 있습니다.

q = deque([(0,99)])

print(q)

distance , node = q.pop()
print('distance:',distance,'node:',node)

 

 

오늘은 deque를 사용하며, 발생했던 TypeError에 대해서 정리해보았습니다.

진짜 오늘도 기본이 중요함을 뼈저리게 깨달으면서 포스팅을 마치겠습니다.

읽어주셔서 감사합니다.

+ Recent posts