字典方法dict.keys(),dict.items() 和dict.values()返回「views」 而不是列表。 http://docs.python.org/dev/3.0/whatsnew//3.0.htmlPython 3.0 - dict方法返回視圖 - 爲什麼?
首先,視圖與迭代器有什麼不同?其次,這種改變的好處是什麼?這是出於性能原因嗎?
它對我來說並不直觀,即我要求一個事物列表(給我所有的鑰匙),並且我還得到其他的東西。這會讓人迷惑嗎?
字典方法dict.keys(),dict.items() 和dict.values()返回「views」 而不是列表。 http://docs.python.org/dev/3.0/whatsnew//3.0.htmlPython 3.0 - dict方法返回視圖 - 爲什麼?
首先,視圖與迭代器有什麼不同?其次,這種改變的好處是什麼?這是出於性能原因嗎?
它對我來說並不直觀,即我要求一個事物列表(給我所有的鑰匙),並且我還得到其他的東西。這會讓人迷惑嗎?
您正在有效地獲取一個列表。它只是不是內部列表的副本,而是表現得好像列表只是表示內部狀態一樣。
這與在Java中實現的方式相同(也可能是其他許多語言/環境)。
主要原因是,對於許多用例來說,返回完全分離的列表是不必要和浪費的。這將需要複製整個內容(可能或很多不是很多)。
如果您只是想遍歷鍵,則不需要創建新列表。如果你真的需要它作爲一個單獨的列表(作爲副本),那麼你可以很容易地從視圖中創建該列表。
約阿希姆紹爾的答案很好地解釋了爲什麼list
沒有返回。但是這留下了爲什麼這些函數不會返回迭代器的問題,就像iteritems
等在Python 2中做的那樣。
迭代器比容器更具限制性。例如,迭代器不允許超過一次傳遞;如果你嘗試第二遍,你會發現它是空的。因此,容器支持諸如elem in cont
之類的操作,但迭代器不支持這種操作:一旦檢查了迭代器中的元素是否在「in」中,迭代器就會被破壞!
另一方面,獲取容器通常要求需要複製,如從字典的鍵中創建列表。
view
對象具有兩全其美:它表現爲一個容器,但不會製作字典的副本!實際上,它是一種虛擬只讀容器,通過鏈接到底層字典來工作。我不知道它是否在標準Python的其他地方出現過。
編輯:
@AntonyHatchkins:它不返回發電機功能的原因是,它不會允許快速in
操作。是的,in
適用於發電機功能(當你打電話給他們時)。也就是說,你可以這樣做:
def f():
for i in range(10):
yield i
5 in f() # True
但根據in
的定義,如果右側是一臺發電機,蟒蛇將通過所有的n
項目發電機 - 導致O(n)
時間複雜度。你無能爲力,因爲這是唯一有意義的行爲,是一個任意的發生器。
在另一方面,在字典視圖的情況下,可以實現in
你喜歡的任何方式,因爲你知道更多關於你的管理數據。而事實上in
與使用哈希表的O(1)
複雜性來實現。您可以通過運行
>>> d = dict(zip(range(50000000), range(50000000)))
>>> 49999999 in d
True
>>> 49999999 in iter(d) # kinda how generator function would work
True
>>>
,並注意到第一in
的速度有多快相比,第二in
檢查。
正如相關的問題已經提到,鑑於有len()
方法,它的迭代器缺乏(尚未清單有它)。
返回一個視圖而不是列表的另一個好處是,至少在鍵它在O(1)操作,而不是O(N)的列表(或迭代)優化的會員資格測試。
這是計算器上一個偉大的回答: http://stackoverflow.com/questions/8957750/what-are-python-dictionary-view-objects – Exthen 2013-11-21 01:26:01
貌似網址是死的。 – Borealis 2016-05-02 01:01:55