Что такое объекты представления словаря?

в python 2.7 мы получили способы представления словаря доступен.

теперь я знаю за и против следующего:

  • dict.items()values, keys): возвращает список, так что вы можете сохранить результат, и
  • dict.iteritems() (и тому подобное): возвращает генератор, поэтому вы можете перебирать каждое значение, сгенерированное по одному.

каковы dict.viewitems() (и нравится)? Каковы их преимущества? Как это работает? В конце концов, что такое вид?

Я читал, что представление всегда отражает изменения из словаря. Но как она ведет себя с точки зрения производительности и памяти? Каковы " за " и "против"?

5 ответов


представления Словаря по существу то, что их название говорит:вид просто как окно о ключах и значениях (или элементах) словаря. Вот отрывок из официальная документация для 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().)

этот пример показывает динамический характер представления: вид клавиш не копия ключей в данный момент времени, но довольно простое окно, которое показывает вам ключи; если они изменены, то то, что вы видите через окно, также меняется. Эта функция может быть полезна в некоторых случаях(например, можно работать с представлением на ключах в нескольких частях программы вместо пересчета текущего списка ключей каждый раз, когда они необходимы) - обратите внимание, что если ключи словаря изменяются во время итерации по представлению, как итератор должен вести себя не очень хорошо определен, что может привести к ошибки.

одно преимущество это просмотр at, скажем, ключи использует только небольшой и фиксированный объем памяти и требует небольшое и фиксированное количество процессорного времени, поскольку нет создания списка ключей (Python 2, с другой стороны, часто излишне создает новый список, как цитирует Rajendran T, который занимает память и время в количестве, пропорциональном длине списка). Продолжить аналогию с окном, если хотите чтобы увидеть пейзаж за стеной, вы просто делаете в нем отверстие (вы строите окно); копирование ключей в список будет соответствовать вместо рисования копии пейзажа на стене-копия занимает время, пространство и не обновляется.

подводя итог, представления просто ... представления (окна) в вашем словаре, которые показывают содержимое словаря даже после его изменения. Они предлагают функции, которые отличаются от списков: список ключей содержит скопировать ключи словаря в данный момент времени, в то время как представление является динамическим и гораздо быстрее получить, так как он не должен копировать любые данные (ключи и значения) для того, чтобы быть создан.


как вы упомянули dict.items() возвращает копию списка словаря пар (ключ, значение), который является расточительным и dict.iteritems() возвращает итератор по парам словаря (ключ, значение).

Теперь возьмем следующий пример, чтобы увидеть разницу между интератор в 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. вид "псевдо-набор-как", в том, что они не поддерживают индексацию, так что с ними можно сделать-это проверить членство и перебрать их (потому что ключи hashable и уникально, ключи и предметы, взгляды более "установить как" в том, что они не содержат дубликатов).
  2. вы можете хранить их и использовать их несколько раз, как версии списка.
  3. потому что они отражают базовый словарь, любое изменение в словаре изменит представление, и будет почти наверняка изменить порядок перебора. Поэтому, в отличие от версий списка, они не "стабильны".
  4. поскольку они отражают базовый словарь, они почти наверняка являются небольшими прокси-объектами; копирование ключей / значений / элементов потребует, чтобы они каким-то образом смотрели исходный словарь и копировали его несколько раз, когда происходят изменения, что было бы абсурдной реализацией. Так что я ожидал очень мало накладных расходов памяти, но доступ будет немного медленнее, чем непосредственно к словарю.

поэтому я думаю, что ключевой usecase-это если вы держите словарь вокруг и многократно повторяете его ключи/элементы/значения с изменениями между ними. Вы можете просто использовать вид вместо этого, поворачивая for k, v in mydict.iteritems(): на for k, v in myview:. Но если вы просто повторяете словарь один раз, я думаю, что ITER - версии по-прежнему предпочтительнее.


методы view возвращают список (не копию списка, по сравнению с .keys(), .items() и .values()), поэтому он более легкий, но отражает текущее содержимое словаря.

С Python 3.0 - методы dict возвращают представления-почему?

основная причина в том, что для многих случаев использования возврат полностью отсоединенный список ненужен и расточителен. Это потребует копирования весь контент (который может быть или не быть много).

Если вы просто хотите перебирать ключи, создайте новый список не обязательный. И если вам действительно нужно это как отдельный список (как копия), то вы можете легко создать список из поля зрения.


представления позволяют получить доступ к структуре данных подложки, не копируя ее. Помимо того, что они динамичны, а не создают список, одним из их наиболее полезных применений является