본문 바로가기
프로그래밍/파이썬

Dictionary changed size during iteration(feat. defaultdict)

by 망고데이 2020. 12. 5.
반응형

상황:

for loop에서 딕셔너리를 iteration하려고 합니다. 그래서 dict.keys() 사용했습니다. 

 

그런데 다음과 같은 에러가 발생했습니다.

구글링을 해본 결과..

1. keys는 iterable을 반환한다고 합니다.

즉, iteration을 진행하는 과정에서 iterable의 크기가 변경이 되면 위와 같은 에러가 발생합니다.

구글링한 대부분의 케이스에서는 iteration을 하는 중에 pop을 하는 과정 혹은 key를 제거하는 로직이 포함되어 있었는데 저는 그런 로직은 없었습니다.

한 가지 제 케이스가 특이했던 부분은 defaultdict를 dictionary로 사용했던 점입니다. defaultdict는 key가 있으면 그 key에 대해 operation을 수행하고, 없으면 지정한 default를 만들어주는 녀석입니다.

제 로직 중에는 내부에 이런 로직을 가지고 있었는데 current_node라는 key가 없는 경우 에러가 나는 것이 아닌, default 값을 만들어주었기 때문에 graph라는 dictionary의 사이즈가 변경되어 에러가 발생했던 것입니다.

for child in graph[current_node]:

 

이에 대한 해결 방법은:

1. "기존의 graph를 copy해서 사용한다."

이렇게 사용하면 iteration에 사용하는 iterable은 사이즈가 고정이기 때문에 문제가 해결됩니다.

2. "list로 감싸준다."

유사한 방법인데, list(dict) 혹은 list(dict.keys())를 함으로써 list라는 고정된 길의 iterable을 사용하도록 수정해줍니다.

3. "iteration 내에서 key가 있는지 체크해준다"

defaultdict를 사용하는 경우에는 key가 없을 때 자동으로 default 값을 갖는 key를 만들어줍니다. 그렇기 때문에 체크를 해주는 것도 한 가지 방법이 될 수 있습니다. 

 

끗.

 

 

반응형

'프로그래밍 > 파이썬' 카테고리의 다른 글

deque(collection)  (0) 2020.12.12
is vs ==  (0) 2020.12.12