콘텐츠로 건너뛰기

키 에러를 해결하는 방법은 무엇인가요? (Python KeyError)

CodeMDD.io

Python KeyError 예외와 처리 방법

Python의 KeyError 예외는 초보자들이 자주 마주치는 예외입니다. KeyError가 발생하는 이유를 알고 이를 방지하기 위한 몇 가지 해결책을 알아보는 것은 Python 프로그래머로서 성장하는 데 필수적인 단계입니다.

이 튜토리얼의 마지막까지 알게 될 내용:

  • Python에서 KeyError가 일반적으로 무엇을 의미하는지
  • 표준 라이브러리에서 KeyError를 어디에서 더 볼 수 있는지
  • KeyError를 처리하는 방법

Python KeyError의 의미

Python의 공식 문서KeyError가 매핑 키에 접근했을 때 해당 키가 매핑 내에서 찾을 수 없는 경우 발생한다고 설명하고 있습니다. 매핑은 하나의 값 집합을 다른 값 집합으로 대응시키는 데이터 구조입니다. Python에서 가장 일반적인 매핑은 사전입니다.

Python KeyErrorLookupError 예외의 유형으로, 찾으려는 키를 검색하는 데 문제가 있음을 나타냅니다. KeyError를 보게 된다면 의미적으로는 찾으려는 키를 찾을 수 없었다는 것을 의미합니다.

아래의 예시를 보면 사람들의 나이를 나타내는 사전(ages)이 정의되어 있습니다. 이 사전에 없는 키에 접근하려고 시도하면 KeyError가 발생합니다:

Python

>>> ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
>>> ages['Michael']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Michael'

이 예시에서는 ages 사전에서 'Michael' 키를 접근하려 하지만 KeyError가 발생합니다. traceback의 맨 아래에는 관련 정보가 표시됩니다:

  • KeyError가 발생했음을 나타내는 사실
  • 찾을 수 없었던 키인 'Michael'

끝에서 두 번째 줄은 예외를 발생시킨 라인을 알려줍니다. 이 정보는 파일에서 Python 코드를 실행할 때 더 유용합니다.

참고: Python에서 예외가 발생하면 traceback와 함께 발생합니다. traceback는 예외가 발생한 이유와 그 원인을 파악할 수 있는 모든 관련 정보를 제공합니다.

아래의 프로그램에서는 다시 ages 사전이 정의되어 있습니다. 이번에는 입력 받은 사람 이름에 해당하는 나이를 조회하도록 할 것입니다:

Python

1# ages.py
2
3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
4person = input('나이를 조회할 사람: ')
5print(f'{person}의 나이는 {ages[person]}살 입니다.')

이 코드는 프롬프트에서 제공하는 이름을 받아 해당 사람의 나이를 조회하려고 시도합니다. 프롬프트에서 입력한 값을

가지고 와서 사전에서 해당하는 사람의 나이를 조회하려고 합니다. 입력할 때 무엇을 입력하든 KeyError가 발생합니다. 왜냐하면 입력한 이름을 키로 사용하여 값을 조회하지만 그 키가 ages 사전에 없기 때문입니다. 이 예제는 KeyError 예외를 처리하지 않고 예외가 발생하는 경우를 보여줍니다.

표준 라이브러리에서 KeyError를 더 볼 수 있는 경우

표준 라이브러리에서 KeyError를 더 자주 만날 수 있는 몇 가지 사례가 있습니다. 몇 가지 예시를 살펴보겠습니다.

dictget() 메서드

dict 클래스의 get() 메서드는 키에 해당하는 값을 반환합니다. 키가 존재하지 않는 경우 기본값을 반환하는 기능을 제공합니다. 기본값이 지정되지 않은 경우 None을 반환합니다. get() 메서드는 KeyError를 일으키지 않기 때문에 코드에서 키의 존재 여부를 확인할 때 유용합니다.

예를 들어, 위의 예제를 get() 메서드를 사용하여 다시 작성하면 다음과 같습니다:

Python

1# ages.py
2
3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
4person = input('나이를 조회할 사람: ')
5age = ages.get(person)
6if age is None:
7 print(f'{person}의 나이를 찾을 수 없습니다.')
8else:
9 print(f'{person}의 나이는 {age}살 입니다.')

이제 get() 메서드를 사용하여 사전에서 고려하고자 하는 사람의 나이를 찾습니다. 경우에 따라 나이를 찾지 못할 수 있으므로 None을 반환하는지 확인합니다. 반환된 age 값이 None인 경우 '나이를 찾을 수 없습니다.'를 출력하고 그렇지 않은 경우 해당 나이를 출력합니다.

collections.defaultdict 클래스

collections.defaultdict 클래스는 존재하지 않는 키에 접근할 때마다 기본값을 반환하는 사전과 같은 동작을 갖습니다. 예를 들어, 다음과 같이 defaultdict를 사용하여 원하는 기본값을 지정할 수 있습니다:

Python

>>> from collections import defaultdict
>>> ages = defaultdict(lambda: '나이를 찾을 수 없습니다.')
>>> ages['Jim'] = 30
>>> ages['Pam'] = 28
>>> ages['Kevin'] = 33
>>> print(ages['Michael'])
나이를 찾을 수 없습니다.

이 예제에서는 defaultdict를 사용하여 사전 ages를 만듭니다. 이제 'Jim', 'Pam', 'Kevin' 키의 값을 설정하는 대신 키가 존재하지 않을 때 반환되는 기본값을 설정합니다. 키 'Michael'에 대한 값을 출력하면 기본값인 '나이를 찾을 수 없습니다.'이 반환됩니다.

defaultdictKeyError를 일으키지 않으며 항상 기본값을 반환하기 때문에 예외를 처리할 필요가 없습니다.

리스트의 index() 메서드

리스트의 index() 메서드는 특정 값을 찾아 해당 값을 가진 인덱스를 반환합니다. 그러나 주의해야 할 점은 index() 메서드가 찾으려는 값이 리스트에 없을 경우 ValueError를 일으킨다는 것입니다. 따라서 index() 메서드를 사용할 때에는 찾으려는 값이 리스트에 존재하는지 확인하는 것이 중요합니다.

str 객체의 index() 메서드

문자열에도 index() 메서드가 있으며 사용 방법은 리스트의 index() 메서드와 동일합니다. 그러나 index() 메서드가 문자열 내에서 찾으려는 부분 문자열을 찾지 못한 경우 ValueError를 일으키는 것을 유의해야 합니다.

따라서 index() 메서드를 사용할 때에는 찾으려는 부분 문자열이 해당 문자열에 존재하는지 확인하는 것이 중요합니다.

내 코드에서 Python KeyError를 발생시킬 때

때로는 코드에서 고의적으로 KeyError를 발생시켜야 할 필요가 있을 수도 있습니다. 이럴 때에는 raise 키워드를 사용하여 KeyError 예외를 일으킬 수 있습니다. 이를 통해 특정 조건에서 키가 존재하지 않을 경우 예외를 발생시킬 수 있습니다.

예를 들어, 다음은 dict 객체에 이미 존재하는 키를 추가할 수 없도록 예외를 발생시키는 코드입니다:

Python

1ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
2name = input('새로운 이름: ')
3if name in ages:
4 raise KeyError(f'{name}은(는) 이미 존재하는 키입니다.')
5else:
6 age = int(input('새로운 나이: '))
7 ages[name] = age

이 코드에서는 name 변수에 새로운 이름을 입력받습니다. 입력받은 이름이 이미 ages 사전의 키로 존재하는 경우 KeyError 예외를 발생시킵니다. 그렇지 않은 경우 새로운 나이를 입력받아 ages에 새로운 항목을 추가합니다.

Python KeyError를 처리하는 방법

Python KeyError를 처리하는 방법에는 여러 가지가 있습니다. 이를 세 가지 방법으로 살펴보겠습니다: .get(), 키 확인, try-except문.

일반적인 해결책: .get()

.get() 메서드는 KeyError를 일으키지 않기 때문에 키의 존재 여부를 확인하는 데 유용합니다. 위에서 언급한 바와 같이 .get() 메서드는 사전에서 키에 해당하는 값을 반환하고, 키가 존재하지 않는 경우 기본값을 반환합니다.

다음 코드는 .get() 메서드를 사용하여 위의 예제를 수정한 것입니다:

Python

1# ages.py
2
3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
4person = input('나이를 조회할 사람: ')
5age = ages.get(person)
6if age is None:
7 print(f'{person}의 나이를 찾을 수 없습니다.')
8else:
9 print(f'{person}의 나이는 {age}살 입니다.')

이제 .get() 메서드를 사용하여 사전에서 원하는 사람의 나이를 검색합니다. 나이를 찾지 못할 수 있는 경우 None을 반환하는지 확인합니다. 반환된 age 값이 None인 경우 '나이를 찾을 수 없습니다.'를 출력하고 그렇지 않은 경우 해당 나이를 출력합니다.

드물게 사용되는 해결책: 키 확인

키가 사전에 있는지 확인하는 다른 방법은 in 키워드를 사용하는 것입니다. 이와 같은 방법은 .get() 메서드 대신 사용할 수 있으며 매우 가독성이 좋습니다.

위의 예제에도 이 방법을 적용해 보겠습니다:

Python

1# ages.py
2
3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
4person = input('나이를 조회할 사람: ')
5if person in ages:
6 print(f'{person}의 나이는 {ages[person]}살 입니다.')
7else:
8 print(f'{person}의 나이를 찾을 수 없습니다.')

이제 키가 ages 사전에 있는지 확인하기 위해 in 키워드를 사용합니다. 키가 존재하는 경우 해당 사람의 나이를 출력하고, 그렇지 않은 경우 '나이를 찾을 수 없습니다.'를 출력합니다.

일반적인 해결책: try-except문

가장 일반적인 방법은 try-except 문을 사용하여 KeyError 예외를 처리하는 것입니다. 이 방법은 예외가 발생할 수 있는 부분을 try 블록으로 둘러싸고, 예외가 발생할 경우 처리할 코드를 except 블록에 작성합니다. 이를 활용하여 위의 예제를 수정하면 다음과 같습니다:

Python

1# ages.py
2
3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33}
4person = input('나이를 조회할 사람: ')
5try:
6 age = ages[person]
7 print(f'{person}의 나이는 {age}살 입니다.')
8except KeyError:
9 print(f'{person}의 나이를 찾을 수 없습니다.')

이제 try-except 문을 사용하여 키가 존재하지 않을 때 발생하는 KeyError 예외를 처리합니다. 키가 존재하는 경우 해당 사람의 나이를 출력하고, 그렇지 않은 경우 '나이를 찾을 수 없습니다.'를 출력합니다.

결론

Python의 KeyError 예외는 주로 dict의 존재하지 않는 키에 접근하는 경우 발생합니다. KeyError가 발생할 때마다 해당 예외의 의미와 이를 처리하는 방법을 알아야 합니다. .get() 메서드, 키 확인, try-except문을 사용하여 KeyError 예외를 처리할 수 있습니다.

Python 프로그래머로서 성장하기 위해 Python traceback를 읽는 방법을 익히고 해당 정보를 활용하는 능력을 기르는 것이 중요합니다.

이 튜토리얼을 통해 Python의 KeyError 예외와 이를 처리하는 방법에 대해 배웠습니다. 이제 자신의 Python 프로그램에서 KeyError를 방지하고, 예외가 발생할 경우 올바르게 처리할 수 있을 것입니다.