我不確定這是不是你的問題的答案,但希望它能解釋一下Python 2和3在這方面的區別。
在Python 2中,iter(d.keys())
和d.iterkeys()
並不完全等價,儘管它們的行爲相同。首先,keys()
將返回字典的密鑰列表的副本,然後iter
將在此列表上返回一個迭代器對象,第二個密鑰的完整列表副本將永遠不會構建。
通過d.keys()
在Python 3返回的視圖對象是迭代(即一個迭代器可以從他們製作),所以當你說for k in d.keys()
Python會爲你創建的迭代器。因此你的兩個例子將表現相同。
keys()
返回類型變化的意義在於Python 3視圖對象是動態的。即如果我們說ks = d.keys()
並且稍後添加到d
那麼ks
將反映這一點。在Python 2中,keys()
返回字典中當前所有鍵的列表。比較:
的Python 3
>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
dict_keys(['second', 'first'])
>>> d["third"] = 3
>>> ks
dict_keys(['second', 'third', 'first'])
的Python 2.x的
>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
['second', 'first']
>>> d["third"] = 3
>>> ks
['second', 'first']
對於Python 3的keys()
返回動態對象的Python 3沒有(和有沒有必要)單獨的iterkeys
方法。
進一步澄清
在Python 3,keys()
返回dict_keys
對象,但如果我們在for
環上下文for k in d.keys()
使用它然後迭代器被隱式地創建。所以for k in d.keys()
和for k in iter(d.keys())
之間的區別是迭代器的隱式或顯式創建之一。
就另一個區別而言,雖然它們都是動態的,但請記住,如果我們創建顯式迭代器,那麼它只能使用一次,而視圖可以根據需要重用。例如
>>> ks = d.keys()
>>> 'first' in ks
True
>>> 'second' in ks
True
>>> i = iter(d.keys())
>>> 'first' in i
True
>>> 'second' in i
False # because we've already reached the end of the iterator
另外,還要注意,如果我們建立一個明確的迭代器,然後修改字典那麼迭代器失效:
>>> i2 = iter(d.keys())
>>> d['fourth'] = 4
>>> for k in i2: print(k)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
在Python 2,鑑於keys
現有的行爲,需要一個單獨的方法提供一種迭代的方式,而不需要複製鍵的列表,同時仍然保持向後兼容性。因此iterkeys()
2.7中有'.viewkeys()'。它返回視圖。 http://docs.python.org/library/stdtypes.html#dict.viewkeys – phadej 2010-09-01 11:23:10
謝謝。我理解Python 2的'd.keys()'是如何不同的。但是我仍然對Python 2中的'd.iterkeys()',Python 3中的'd.keys()'和Python 3中的'iter(d.keys())'之間的區別感到困惑。據我瞭解,他們都是充滿活力的,他們都沒有提前列出清單? – max 2010-09-01 11:41:13
在'for'循環中,'iter(d.keys())'和'd.keys()'沒有區別,因爲python內部調用iter'本身。 python 2.x'd.iterkeys()'和py3k'iter(d.keys())'之間也沒有區別:都返回dictionary-key-iterator。所以三者幾乎都是一樣的。 – phadej 2010-09-01 12:02:39