Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python TypeError: unhashable type: 'slice' 오류 원인과 해결 방법

파이썬 딕셔너리(dictionary)의 값은 리스트처럼 슬라이싱할 수 없습니다. 딕셔너리는 0부터 시작하는 숫자 인덱스가 아니라 사용자가 정의한 키(key)로 데이터를 저장하기 때문입니다. 딕셔너리를 리스트처럼 슬라이싱하려고 하면 "TypeError: unhashable type: 'slice'" 오류가 발생합니다.

이 글에서는 이 오류가 무엇을 의미하는지, 왜 코드에서 발생하는지 살펴보고, 실제 예시를 통해 해결 방법까지 안내합니다.

TypeError: unhashable type: 'slice' 오류란?

슬라이스(slice)는 문자열, 리스트, 튜플 같은 시퀀스(sequence)의 일부분을 의미합니다. 이름 그대로 시퀀스를 "잘라낸 한 조각"이라는 뜻입니다.

다음 프로그램을 살펴보겠습니다.

news_sites = ["New York Times", "Washington Post", "CNN"]
print(news_sites[:2])

이 코드는 news_sites 리스트에서 처음 두 개의 값을 가져와 콘솔에 출력합니다. 실행 결과는 다음과 같습니다.

['New York Times', 'Washington Post']

이것이 바로 슬라이싱입니다. 콜론(:)과 인덱스 값을 지정하면 파이썬이 어떤 요소를 가져올지 판단합니다.

하지만 딕셔너리는 리스트처럼 슬라이싱할 수 없습니다. 딕셔너리에는 인덱스 번호가 없기 때문에 이 문법이 적용되지 않습니다.

오류 발생 예시

컴퓨터 하드웨어 매장에서 판매 중인 키보드 정보를 보여주는 프로그램을 만들어 보겠습니다. 먼저 키보드 정보를 담은 딕셔너리를 정의합니다.

keyboard = {
    "name": "Huntsman Mini",
    "brand": "Razer",
    "price": 119.99,
    "switch_type": "Razer Switches",
}

이 딕셔너리에는 키보드 이름, 브랜드, 가격, 스위치 타입 정보가 저장되어 있습니다. 여기서 고객에게는 이름, 브랜드, 가격 세 가지만 보여주고 싶다고 가정해 봅시다.

이를 위해 슬라이싱으로 딕셔너리의 처음 세 항목을 가져오려고 했습니다. 해당 항목은 키보드 이름, 브랜드, 가격입니다.

show_to_customer = keyboard[:3]

그다음 for 루프로 이 결과를 반복하면서 각 항목을 콘솔에 출력하는 코드입니다.

for s in show_to_customer:
    print(s[1])

show_to_customer 변수의 각 레코드에서 인덱싱으로 값을 꺼낸 뒤, print() 문으로 콘솔에 출력하려는 의도입니다. 코드를 실행해 보겠습니다.

Traceback (most recent call last):
  File "main.py", line 8, in <module>
    show_to_customer = keyboard[:3]
TypeError: unhashable type: 'slice'

코드가 오류를 반환합니다.

해결 방법

리스트와 달리 딕셔너리는 슬라이싱할 수 없습니다. 딕셔너리에는 인덱스 번호가 없으므로 슬라이싱으로 항목을 가져올 수 없으며, 데이터는 키-값(key-value) 쌍으로 저장됩니다. 따라서 앞서 작성한 for 루프 방식도 적합하지 않습니다.

딕셔너리에서 원하는 값에 접근하려면 키 이름을 직접 지정해야 합니다. 각 값을 개별적으로 접근하도록 코드를 수정해 보겠습니다.

keyboard = {
    "name": "Huntsman Mini",
    "brand": "Razer",
    "price": 119.99,
    "switch_type": "Razer Switches",
}

print("Name: " + keyboard["name"])
print("Brand: " + keyboard["brand"])
print("Price: $" + str(keyboard["price"]))

각 print() 문은 딕셔너리의 서로 다른 값을 참조합니다. 첫 번째 print 문은 "Name:" 레이블과 함께 딕셔너리의 name 키 값을 출력하고, 두 번째와 세 번째 문은 각각 brand와 price 값을 출력합니다.

price 값은 str() 메서드로 문자열로 변환한 뒤, 문자열 연결 연산자(+)를 사용해 "Price: $" 레이블과 이어 붙였습니다.

수정된 프로그램을 실행하면 다음과 같은 결과가 나옵니다.

Name: Huntsman Mini
Brand: Razer
Price: $119.99

코드가 성공적으로 실행되어 원하는 세 가지 정보가 모두 콘솔에 출력됩니다. 사용자는 키보드의 이름, 브랜드, 가격을 확인할 수 있습니다.

여러 키를 한 번에 가져오는 방법

특정 키들만 골라서 새로운 딕셔너리를 만들고 싶다면 딕셔너리 컴프리헨션(dictionary comprehension)을 활용할 수도 있습니다.

wanted_keys = ["name", "brand", "price"]
show_to_customer = {k: keyboard[k] for k in wanted_keys}
print(show_to_customer)
# {'name': 'Huntsman Mini', 'brand': 'Razer', 'price': 119.99}

이 방식은 키 목록을 기반으로 필요한 항목만 깔끔하게 추출할 수 있어, 슬라이싱 대신 자주 사용되는 패턴입니다.

마무리

"TypeError: unhashable type: 'slice'" 오류는 딕셔너리에 슬라이싱 문법으로 접근하려 할 때 발생합니다. 이 오류를 해결하려면 딕셔너리의 항목에 접근할 때 키 이름을 직접 지정해야 합니다.

이제 이 오류를 전문가처럼 해결할 준비가 되었습니다!