Python3에서 인덱스로 dict_keys 요소에 액세스


131

색인으로 dict_key의 요소에 액세스하려고합니다.

test = {'foo': 'bar', 'hello': 'world'}
keys = test.keys()  # dict_keys object

keys.index(0)
AttributeError: 'dict_keys' object has no attribute 'index'

나는 얻고 싶다 foo.

와 같다:

keys[0]
TypeError: 'dict_keys' object does not support indexing

어떻게해야합니까?


9
py3.x에서는 dict.keys()목록이 아닌보기 객체와 같은 집합을 반환하므로 색인을 생성 할 수 없습니다. 사용keys = list(test)
애쉬 위니 Chaudhary

내가 list (something_dict) 할 때 튜플 순서는 무작위입니다. 예 : list ({ 'foo': 'bar', 'hello': 'world'}) 반환 할 수 있습니다 : list (foo, hello) 또는 list (hello, foo), 왜 이것이 무작위입니까?
fj123x 2009 년

7
Dicts에는 주문이 없습니다 . ( collections.OrderedDict주문 키를 원할 경우 사용 )
Ashwini Chaudhary

스레드 안전에 대한 흥미로운 토론은이 문제를 해결하기위한 다양한 접근 방식을 다시 나타냅니다
Paul

답변:


161

list()대신 사전을 호출 하십시오.

keys = list(test)

Python 3에서 dict.keys()메소드는 사전 역할을하는 사전 뷰 객체를 반환합니다 . 사전을 직접 반복하면 키도 생성되므로 사전을 목록으로 바꾸면 모든 키 목록이 생성됩니다.

>>> test = {'foo': 'bar', 'hello': 'world'}
>>> list(test)
['foo', 'hello']
>>> list(test)[0]
'foo'

3
Python 3에서 list (dict.keys ())를 살펴보십시오. Labix 블로그 는 솔루션을 제공하지 않고 문제가 무엇인지 명확하게 설명합니다. 이것은 우수하다!
Brandon Bradley

@BrandonBradley : 일반적으로 말하기 : 파이썬은 매우 역동적이므로 원자 적 인 특정 행동에 의존하는 것은 나쁜 생각입니다. dict예를 들어, .keys()파이썬 코드에서 처리되는 곳과 같은 서브 클래스를 쉽게 전달할 수 있습니다 (예 : 스레드 전환이 발생할 수 있음).
Martijn Pieters

@BrandonBradley : 링크 주셔서 감사합니다. 해당 블로그에 대한 의견 중 하나의 솔루션 만 Python3에서 작동합니다 : sorted (dict.keys ()). Python2에서 dict.keys ()는 키 값 목록을 반환합니다.
Good Will

2
@GoodWill : sorted(dict)똑같은 일을 할 것입니다; 정렬 된 순서로 키 목록을 생성합니다. list(dict)사전 순서대로 목록을 제공합니다.
Martijn Pieters

1
또는 사용할 수keys = [*test]
Alex78191

59

완전한 대답은 아니지만 유용한 힌트 일 것입니다. 실제로 원하는 첫 번째 항목 인 경우 *

next(iter(q))

보다 훨씬 빠르다

list(q)[0]

모든 것을 메모리에 저장할 필요가 없기 때문에 큰 dicts의 경우.

10.000.000 항목의 경우 거의 40.000 배 빠릅니다.

* dict이 파이썬 3.6 이전의 의사 난수 항목 인 경우 첫 번째 항목 은 표준 구현에서 주문되지만 의존하지 않는 것이 좋습니다.


5
이것은 항상 Py3에서 모든 것이 반복자가되는 가장 큰 문제 중 하나였습니다. 확실히 더 효율적이지만 많은 유스 케이스가 "사악한"이유가되어 복잡해집니다. 예를 들어 성능 손실없이 반복자에서 인덱싱을 지원할 수없는 이유는 무엇입니까?
Ehsan Kia

2

첫 번째 사전 항목의 "키"및 "값"쌍을 원했습니다. 다음 코드를 사용했습니다.

 key, val = next(iter(my_dict.items()))

0
test = {'foo': 'bar', 'hello': 'world'}
ls = []
for key in test.keys():
    ls.append(key)
print(ls[0])

정적으로 정의 된 목록에 키를 추가 한 다음 동일한 색인을 생성하는 기존의 방법


2
잘못된 것은 아니지만 왜 그렇지 ls = list(test.keys())않습니까? 나는 그것이 더 간단하다는 것을 안다.
Valentino

예, 더 효율적입니다. 나는 가독성을 보여주기 위해 이것을 썼습니다.
pranav dua

0

많은 경우에 이것은 XY 문제 일 수 있습니다 . 위치별로 사전 키를 색인화하는 이유는 무엇입니까? 정말로해야합니까? 최근까지 파이썬에서는 사전을 주문하지 않았으므로 첫 번째 요소에 액세스하는 것은 임의적이었습니다.

방금 Python 2 코드를 Python 3으로 변환했습니다.

keys = d.keys()
for (i, res) in enumerate(some_list):
    k = keys[i]
    # ...

예쁘지는 않지만 나쁘지는 않습니다. 처음에, 나는 그것을 괴물로 대체하려고했습니다.

    k = next(itertools.islice(iter(keys), i, None))

내가이 모든 것이 훨씬 낫다는 것을 깨닫기 전에

for (k, res) in zip(d.keys(), some_list):

잘 작동합니다.

다른 많은 경우에는 위치별로 사전 키 인덱싱을 피할 수 있다고 생각합니다. 파이썬 3.7에서 사전이 주문되었지만 그것에 의존하는 것은 그리 좋지 않습니다. 위의 코드는의 콘텐츠 some_list가 최근의 콘텐츠로 제작 되었기 때문에 작동합니다 d.

disk_keys인덱스 로 요소에 실제로 액세스해야하는 경우 코드를 자세히 살펴보십시오 . 아마도 당신은 필요하지 않습니다.


0

이 시도

keys = [next(iter(x.keys())) for x in test]
print(list(keys))

결과는 다음과 같습니다. [ 'foo', 'hello']

더 많은 솔루션을 여기에서 찾을 수 있습니다 .

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