IT story

사전 뷰 객체 란 무엇입니까?

hot-time 2020. 6. 14. 09:52
반응형

사전 뷰 객체 란 무엇입니까?


파이썬 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()오류가 발생했을 수 있습니다.


문서를 읽음으로써 나는이 인상을 얻습니다.

  1. 뷰는 인덱싱을 지원하지 않는다는 점에서 "의사 세트와 유사"하므로 뷰를 사용하여 수행 할 수있는 것은 멤버쉽을 테스트하고 반복합니다 (키는 해시 가능하고 고유하므로 키 및 항목 뷰는 " 중복되지 않습니다 ").
  2. 목록 버전과 같이 저장하고 여러 번 사용할 수 있습니다.
  3. 기본 사전을 반영하므로 사전을 변경하면보기가 변경되고 반복 순서거의 확실하게 변경 됩니다. 따라서 목록 버전과 달리 "안정적"이 아닙니다.
  4. Because they reflect the underlying dictionary, they're almost certainly small proxy objects; copying the keys/values/items would require that they watch the original dictionary somehow and copy it multiple times when changes happen, which would be an absurd implementation. So I would expect very little memory overhead, but access to be a little slower than directly to the dictionary.

So I guess the key usecase is if you're keeping a dictionary around and repeatedly iterating over its keys/items/values with modifications in between. You could just use a view instead, turning for k, v in mydict.iteritems(): into for k, v in myview:. But if you're just iterating over the dictionary once, I think the iter- versions are still preferable.


The view methods return a list(not a copy of the list, compared to .keys(), .items() and .values()), so it is more lightweight, but reflects the current contents of dictionary.

From Python 3.0 - dict methods return views - why?

The main reason is that for many use cases returning a completely detached list is unnecessary and wasteful. It would require copying the entire content (which may or many not be a lot).

If you simply want to iterate over the keys then creating a new list is not necessary. And if you indeed need it as a separate list (as a copy) then you can easily create that list from the view.


Views let you access the underlaying data structure, without copying it. Besides being dynamic as opposed to creating a list, one of their most useful usage is in test. Say you want to check if a value is in the dict or not (either it be key or value).

Option one is to create a list of the keys using dict.keys(), this works but obviously consumes more memory. If the dict is very large? That would be wasteful.

With views you can iterate the actual data-structure, without intermediate list.

Let's use examples. I've a dict with 1000 keys of random strings and digits and k is the key I want to look for

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?

As you can see, iterating view object gives a huge boost to performance, reducing memory overhead at the same time. You should use them when you need to perform Set like operations.

Note: I'm running on Python 2.7

참고URL : https://stackoverflow.com/questions/8957750/what-are-dictionary-view-objects

반응형