TypeError : 'dict_keys'개체가 인덱싱을 지원하지 않습니다


144
def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.
    """

    randbelow = self._randbelow
    for i in reversed(range(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = randbelow(i+1) if random is None else int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

shuffle함수를 실행할 때 다음 오류가 발생합니다. 왜 그럴까요?

TypeError: 'dict_keys' object does not support indexing

7
python3 오류 인 것 같습니다
DataEngineer

답변:


231

분명히 당신은 d.keys()당신의 shuffle기능에 전달하고 있습니다. 아마도 이것은 python2.x로 작성되었습니다 ( d.keys()목록을 반환 할 때 ). python3.x를 사용하면 a 보다 훨씬 많이 작동 d.keys()하는 dict_keys객체를 반환 set합니다 list. 따라서 색인을 생성 할 수 없습니다.

용액을 통과하는 list(d.keys())(또는 간단히 list(d)하기 위해) shuffle.


22
. . . 또는 list(d)복사하지 않고 python2.x와 python3.x의 키 목록을 제공합니다 :-)
mgilson

11
이것은 python3에 대한 이상한 변경 디자인 결정입니다.
Jason

9
당신은 그렇게 생각할 수도 있지만, 나는 그것이 올바른 결정이라고 생각합니다. dict_keys개체가 많은 더 딕셔너리 단지 키의 절반처럼 동작합니다. 특히, 그들은 O (1) 멤버쉽 테스트 (및 그 사실 위에 효율적으로 구현 될 수있는 다른 세트와 유사한 메소드)를 지원합니다. 이러한 것들은 목록으로는 불가능하며, dict의 키 목록을 원한다면 항상 간단하게 list(your_dictionary)얻을 수 있습니다.
mgilson 2016 년

이것은 python3이 사전을 목록으로 감싸 야한다는 것을 알기 위해 도움이됩니다.
DataEngineer

2
@Crt- shuffle원본 포스터 코드의 함수 이름입니다 (오류가 발생하는 함수). 코드를 살펴보면 random.shuffle표준 라이브러리의 구현에서 복사 / 붙여 넣은 것으로 생각됩니다 :-)
mgilson

11

결과를 somedict.keys()함수에 전달합니다 . Python 3에서는 dict.keys목록을 반환하지 않지만 사전 키의 뷰를 나타내고 집합과 같은 집합 같은 개체는 인덱싱을 지원하지 않습니다.

문제를 해결하려면 list(somedict.keys())키를 수집하고이를 사용 하여 작업하십시오.


10

iterable을 목록으로 변환하면 비용이 발생할 수 있습니다. 대신 첫 번째 항목을 얻으려면 다음을 사용할 수 있습니다.

next(iter(keys))

또는 모든 항목을 반복하려면 다음을 사용할 수 있습니다.

items = iter(keys)
while True:
    try:
        item = next(items)
    except StopIteration as e:
        pass # finish

1

셔플이 이미 존재하는 경우 왜 구현해야합니까? 거인의 어깨에 머 무르십시오.

import random

d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
     5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}

keys = list(d1)
random.shuffle(keys)

d2 = {}
for key in keys: d2[key] = d1[key]

print(d1)
print(d2)

대답은 일반적인 지식과 관련이 있지만 OP가 요청한 내용을 다루지는 않습니다.
JC Rocamonde

네가 옳아. 그는 자신의 무작위 추출기를 구현하고 싶어하는 것 같습니다.
FooBar167

1
psah, 그는 내장을 사용할 수 있다는 것을 실제로 몰랐지만 질문은 실제로 유형 오류에 관한 것 같습니다. 그럼에도 불구하고 그가 기본적인 DRY와 코드 경제 원칙을 따르기 위해 (특별한 것이 아닌 한) 당신의 선택을 바꾸고 사용하기를 바랍니다.
JC Rocamonde

1

Python 2에서는 dict.keys ()가 목록을 반환하지만 Python 3에서는 생성기를 반환합니다.

당신은 그것의 값을 반복 할 수 있습니다. 그렇지 않으면 그것을 명시 적으로 목록으로 변환해야합니다. 즉, 목록 함수에 전달하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.