파이썬 2.7에서는 사전보기 메소드를 사용할 수 있습니다.
이제 다음과 같은 장단점을 알고 있습니다.
dict.items()
(와values
,keys
) : 당신이 실제로 결과를 저장할 수 있도록 목록을 반환하고,dict.iteritems()
(및 기타) : 생성기를 반환하므로 생성 된 각 값을 하나씩 반복 할 수 있습니다.
무엇을 dict.viewitems()
위한 것입니까? 그들의 장점은 무엇입니까? 어떻게 작동합니까? 결국은 무엇입니까?
뷰가 항상 사전의 변경 사항을 반영한다는 것을 읽었습니다. 그러나 성능 및 메모리 관점에서 어떻게 작동합니까? 장단점은 무엇입니까?
답변
사전보기는 본질적으로 그 이름이 말하는 것입니다. 보기는 단순히 사전의 키 및 값 (또는 항목)의 창과 같습니다 . 다음은 Python 3 공식 문서 에서 발췌 한 것입니다 .
>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()
>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> keys # No eggs anymore!
dict_keys(['sausage', 'bacon', 'spam'])
>>> values # No eggs value (2) anymore!
dict_values([1, 1, 500])
(Python 2와 동등한 사용 dishes.viewkeys()
및 dishes.viewvalues()
.)
이 예제 보여줍니다 뷰의 동적 특성 : 키가 볼 수는 없는 특정 시점에서 키의 복사본이 아니라 단순한 창을 보여줍니다 당신의 키; 그것들이 변경되면, 당신은 창을 통해 보이는 것이 변경됩니다. 이 기능은 일부 상황에서 유용 할 수 있습니다 (예 : 필요할 때마다 현재 키 목록을 다시 계산하는 대신 프로그램의 여러 부분에서 키를 볼 수 있음) — 사전 키가 수정 된 경우 뷰를 반복하는 동안 이터레이터의 동작 방식이 제대로 정의되지 않아 오류가 발생할 수 있습니다 .
하나의 장점이다 보는 말은 키만을 사용에서 메모리의 적은 고정 된 양 및 필요한 프로세서 시간 작고 일정량 키의 목록에는 생성이 없으므로 한편, 파이썬 2- ( Rajendran T에 의해 인용 된대로 목록의 길이에 비례하는 양의 메모리와 시간이 걸리는 경우가 종종 필요하지 않습니다. 창 비유를 계속하려면 벽 뒤의 풍경을 보려면 간단히 그 안에 개구부를 만드십시오 (창을 만듭니다). 키를 목록에 복사하면 벽에 가로 사본을 페인팅하는 것과 같습니다. 사본에는 시간, 공간이 걸리고 자체 업데이트되지 않습니다.
요약하면, 뷰는 단순히 사전에있는 뷰 (창)이며 사전이 변경된 후에도 사전의 내용을 표시합니다. 그것들은 목록의 기능과 다른 기능을 제공합니다. 키 목록에는 주어진 시점에 사전 키 의 사본 이 포함되어 있지만 뷰는 동적이며 데이터를 복사 할 필요가 없으므로 훨씬 빨리 얻을 수 있습니다 ( 키 또는 값)을 생성합니다.
답변
언급했듯이 dict.items()
사전 (키, 값) 쌍의 사전 목록 사본을 반환하고 사전 (키, 값) 쌍에 dict.iteritems()
대한 반복자를 반환합니다.
이제 dict의 interator와 dict의 관점의 차이점을 보려면 다음 예를 사용하십시오.
>>> d = {"x":5, "y":3}
>>> iter = d.iteritems()
>>> del d["x"]
>>> for i in iter: print i
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
보기에는 단순히 dict의 내용이 표시됩니다. 변경되었는지는 중요하지 않습니다.
>>> d = {"x":5, "y":3}
>>> v = d.viewitems()
>>> v
dict_items([('y', 3), ('x', 5)])
>>> del d["x"]
>>> v
dict_items([('y', 3)])
뷰는 단순히 사전이 지금 보이는 모습입니다. 삭제 후 항목 .items()
이 오래되어 .iteritems()
오류가 발생했을 수 있습니다.
답변
문서를 읽음으로써 나는이 인상을 얻습니다.
- 뷰는 인덱싱을 지원하지 않는다는 점에서 “의사 세트와 유사”하므로 뷰를 사용하여 수행 할 수있는 것은 멤버쉽을 테스트하고 반복합니다 (키는 해시 가능하고 고유하기 때문에 키 및 항목 뷰는 ” 중복되지 않습니다 “).
- 목록 버전과 같이 저장하고 여러 번 사용할 수 있습니다.
- 기본 사전을 반영하므로 사전을 변경하면보기가 변경되고 반복 순서 가 거의 확실하게 변경 됩니다. 따라서 목록 버전과 달리 “안정적”이 아닙니다.
- 그것들은 기본 사전을 반영하기 때문에 거의 작은 프록시 객체입니다. 키 / 값 / 항목을 복사하려면 어쨌든 원래 사전을보고 변경이 발생할 때 여러 번 복사해야합니다. 따라서 메모리 오버 헤드가 거의 필요하지 않지만 사전에 직접 액세스하는 것보다 액세스 속도가 약간 느립니다.
따라서 핵심 유스 케이스는 사전을 유지하고 키 / 항목 / 값을 반복하여 반복하여 반복하는 경우입니다. 대신 뷰를 사용하여 for k, v in mydict.iteritems():
로 전환 할 수 for k, v in myview:
있습니다. 그러나 사전을 한 번 반복하는 경우 반복 버전이 여전히 바람직하다고 생각합니다.
답변
뷰 방법은 목록 (안 비교 목록의 복사본을 반환 .keys()
, .items()
및 .values()
더 경량이지만, 사전의 현재 내용을 반영하므로).
에서 파이썬 3.0 – DICT 방법은 뷰를 반환 – 왜?
주된 이유는 많은 사용 사례에서 완전히 분리 된 목록을 반환하는 것이 불필요하고 낭비이기 때문입니다. 전체 내용을 복사해야합니다 (많거나 많지 않을 수도 있음).
단순히 키를 반복하려면 새 목록을 만들 필요가 없습니다. 그리고 실제로 별도의 목록 (사본)으로 필요하면보기에서 해당 목록을 쉽게 만들 수 있습니다.
답변
뷰를 사용하면 언더 레이 데이터 구조를 복사하지 않고 액세스 할 수 있습니다. 목록을 작성하는 대신 역동적 일뿐만 아니라 가장 유용한 사용법 중 하나는 in
테스트입니다. 값이 dict에 있는지 여부를 확인하려고한다고 가정하십시오 (키 또는 값).
옵션 1은을 사용하여 키 목록을 만드는 것입니다. dict.keys()
이 작동하지만 분명히 더 많은 메모리를 소비합니다. dict이 매우 큰 경우? 그것은 낭비입니다.
함께 views
하면 중간리스트를 사용하지 말고, 실제 데이터 구조를 반복 할 수 있습니다.
예제를 사용합시다. 나는 임의의 문자열과 숫자로 된 1000 개의 키를 가진 dict를 가지고 있고 k
내가 찾고 싶은 키입니다.
large_d = { .. 'NBBDC': '0RMLH', 'E01AS': 'UAZIQ', 'G0SSL': '6117Y', 'LYBZ7': 'VC8JQ' .. }
>>> len(large_d)
1000
# this is one option; It creates the keys() list every time, it's here just for the example
timeit.timeit('k in large_d.keys()', setup='from __main__ import large_d, k', number=1000000)
13.748743600954867
# now let's create the list first; only then check for containment
>>> list_keys = large_d.keys()
>>> timeit.timeit('k in list_keys', setup='from __main__ import large_d, k, list_keys', number=1000000)
8.874809793833492
# this saves us ~5 seconds. Great!
# let's try the views now
>>> timeit.timeit('k in large_d.viewkeys()', setup='from __main__ import large_d, k', number=1000000)
0.08828549011070663
# How about saving another 8.5 seconds?
보다시피 반복 view
객체는 성능을 크게 향상시켜 동시에 메모리 오버 헤드를 줄입니다. Set
유사한 작업 을 수행해야 할 때 사용해야합니다 .
참고 : Python 2.7에서 실행 중입니다.