알찬정보 툰코 개발 트렌드 이슈 코딩

알찬정보 툰코 개발 트렌드 이슈 코딩

  • [Python] 딕셔너리 수정 중 발생하는 에러 및 해결 방법 RuntimeError: * during iteration

    hellowsydney8010

    2023년 10월 01일
    미분류
    [Python] 딕셔너리 수정 중 발생하는 에러 및 해결 방법 RuntimeError: * during iteration

    How to solve “RuntimeError: * during iteration” in python?

    먼저 어떤 에러가 발생할 수 있는지 여러 dictionary로 재현해보겠습니다.

    하고자 하는 task는 딕셔너리의 “key2”인 key를 삭제하는 것입니다. “key1”, “key2”, “key3”를 dict에 넣고 “key2”를 삭제하면 기대되는 아웃풋은 “key1”, “key3”만 남은 dict입니다.

    재현 1 (dict)

    [Code]

    dictionary = {"key1":1, "key2":2, "key3":3}
    
    for key in dictionary.keys():
        if "key2" in key:
            del(dictionary[key])        
    

    [Output]

    ---------------------------------------------------------------------------
    RuntimeError                              Traceback (most recent call last)
    <ipython-input-91-ca7288b8a62c> in <module>
          1 dictionary = {"key1":1, "key2":2, "key3":3}
          2 
    ----> 3 for key in dictionary.keys():
          4     if "key2" in key:
          5         del(dictionary[key])
    
    RuntimeError: dictionary changed size during iteration
    

    재현 2 (defaultdict)

    [Code]

    from collections import defaultdict 
    
    dictionary = defaultdict() 
    dictionary["key1"] = 1
    dictionary["key2"] = 2
    dictionary["key3"] = 3
    
    for key in dictionary.keys():
        if "key2" in key:
            dictionary.pop(key)
    

    [Output]

    ---------------------------------------------------------------------------
    RuntimeError                              Traceback (most recent call last)
    <ipython-input-92-38c7499c969a> in <module>
          6 dictionary["key3"] = 3
          7 
    ----> 8 for key in dictionary.keys():
          9     if "key2" in key:
         10         dictionary.pop(key)
    
    RuntimeError: dictionary changed size during iteration
    

    재현 3 (OrderedDict)

    [Code]

    from collections import OrderedDict 
    
    dictionary = OrderedDict() 
    dictionary["key1"] = 1
    dictionary["key2"] = 2
    dictionary["key3"] = 3
    
    for key in dictionary.keys():
        if "key2" in key:
            del(dictionary[key])
    

    [Output]

    ---------------------------------------------------------------------------
    RuntimeError                              Traceback (most recent call last)
    <ipython-input-93-c8006cf54e87> in <module>
          6 dictionary["key3"] = 3
          7 
    ----> 8 for key in dictionary.keys():
          9     if "key2" in key:
         10         del(dictionary[key])
    
    RuntimeError: OrderedDict mutated during iteration
    

    3가지 dict에서 발생할 수 있는 같은 형태의 error를 재현했습니다.

    에러는 dict가 반복 실행에서 변경되어 발생하는 에러입니다. 즉 반복 실행 입장에서는 “key2”가 dict에 있어야 하는데 없다는 겁니다.

    해결 방법은 copy()를 사용하는 것입니다. 반복 실행에 입력되는 dict을 복사하여 기존 dict이 수정되더라도 반복 실행에서는 문제가 발생하지 않습니다.


    해결 방법

    dictionary를 copy()를 통해 복사하여 반복 실행에 넣어주었고, for문 이하에서 dictionary가 수정되어도 반복 실행의 dictionary와는 전혀 관계가 없죠. 따라서 정상적으로 동작하게 됩니다.

    [Code]

    from collections import defaultdict 
    
    dictionary = defaultdict() 
    dictionary["key1"] = 1
    dictionary["key2"] = 2
    dictionary["key3"] = 3
    
    for key in dictionary.copy().keys(): # copy() 추가
        if "key2" in key:
            dictionary.pop(key)
            
    print(dictionary)
    

    [Output]

    defaultdict(None, {'key1': 1, 'key3': 3})
    

    제가 이 에러를 맞닥뜨린 부분은 신경망 모델을 저장하는 부분에서 특정 layer를 저장할 필요가 없고, 용량이 꽤 크기 때문에 그 특정 layer를 삭제하려했습니다.

    일반적으로 pytorch에서 model.state_dict()을 통해 모델의 파라미터를 dict의 형태로 받아오고 저장합니다. 저장하기 전에 특정 레이어를 제거하려했더니 RuntimeError: * during iteration 가 발생했습니다. copy()를 통해 간단히 해결할 수 있었습니다.

    다음
    이전

    답글 남기기 응답 취소

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Subscribe to Our Newsletter!

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Subscribe Now

Copyright © 2023 Sydney Note

Design by ThemesDNA.com