web-dev-qa-db-ja.com

Dict.items()とdict.iteritems()の違いは何ですか?

dict.items()dict.iteritems() の間に適用可能な違いはありますか?

Pythonのドキュメントから:

dict.items():辞書の(キー、値)ペアのリストの コピー を返します。

dict.iteritems():辞書の(キー、値)ペアに対して イテレータ を返します。

以下のコードを実行すると、それぞれが同じオブジェクトへの参照を返すようです。私が見逃している微妙な違いはありますか?

#!/usr/bin/python

d={1:'one',2:'two',3:'three'}
print 'd.items():'
for k,v in d.items():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'

print 'd.iteritems():'   
for k,v in d.iteritems():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'   

出力:

d.items():
    they are the same object
    they are the same object
    they are the same object
d.iteritems():
    they are the same object
    they are the same object
    they are the same object
626
the wolf

それは進化の一部です。

もともと、Pythonのitems()はタプルの本当のリストを作り、それを返しました。それは潜在的に多くの余分なメモリを取る可能性があります。

その後、ジェネレータは一般的な言語に導入され、そのメソッドはiteritems()という名前のイテレータジェネレータメソッドとして再実装されました。オリジナルは後方互換性のために残っています。

Python 3の変更点の1つは、items()がイテレータを返すようになり、リストが完全に構築されないことです。 Python 3のiteritems()はPython 2.7のitems()のように機能するため、viewitems()メソッドもなくなりました。

769
Keith

dict.items()は2タプルのリスト([(key, value), (key, value), ...])を返しますが、dict.iteritems()は2タプルを生成するジェネレータです。前者は最初はより多くのスペースと時間がかかりますが、各要素へのアクセスは高速ですが、2番目は最初はより少ないスペースと時間がかかりますが、各要素の生成にはもう少し時間がかかります。

Py2.xでは

dict.items()dict.keys()、およびdict.values()コマンドは、辞書の list (k, v)ペア、キー、および値の copy を返します。コピーされたリストが非常に大きい場合、これは大量のメモリを消費する可能性があります。

dict.iteritems()dict.iterkeys()、およびdict.itervalues()コマンドは、辞書の(k, v)のペア、キー、および値に対して イテレータ を返します。

コマンドdict.viewitems()dict.viewkeys()およびdict.viewvalues()は、 ビューオブジェクト を返します。これは、辞書の変更を反映することができます。 (つまり、アイテムにdelを追加したり、辞書に(k,v)ペアを追加した場合、ビューオブジェクトは同時に自動的に変更できます。)

$ python2.7

>>> d = {'one':1, 'two':2}
>>> type(d.items())
<type 'list'>
>>> type(d.keys())
<type 'list'>
>>> 
>>> 
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>
>>> type(d.iterkeys())
<type 'dictionary-keyiterator'>
>>> 
>>> 
>>> type(d.viewitems())
<type 'dict_items'>
>>> type(d.viewkeys())
<type 'dict_keys'>

Py3.xにいる間

Py3.xでは、dict.items()dict.keys()、およびdict.values()のみが利用可能で、Py2.xのdict.viewitems()と同じように viewオブジェクト が返されるため、状況はよりクリーンです。

しかし

@lvcが指摘したように、 view object iterator と同じではないので、Py3.xで iterator を返したい場合は、 iter(dictview)

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>
60
YaOzI

あなたは尋ねました:「dict.items()とdict.iteritems()の間に適切な違いはありますか」

これは役に立つかもしれません(Python 2.xの場合):

>>> d={1:'one',2:'two',3:'three'}
>>> type(d.items())
<type 'list'>
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>

d.items()はキーと値の組のタプルのリストを返し、d.iteritems()は辞書項目区切り文字を返すことがわかります。

リストとして、d.items()はスライス可能です:

>>> l1=d.items()[0]
>>> l1
(1, 'one')   # an unordered value!

しかし__iter__メソッドはありません。

>>> next(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

イテレータとして、d.iteritems()は not slice-ableです。

>>> i1=d.iteritems()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dictionary-itemiterator' object is not subscriptable

しかし__iter__があります:

>>> next(d.iteritems())
(1, 'one')               # an unordered value!

そのため、アイテム自体は同じです。アイテムを配信するコンテナは異なります。 1つはリスト、もう1つはイテレータです(Pythonのバージョンによって異なります)。

そのため、dict.items()とdict.iteritems()の間に適用可能な違いは、リストとイテレータの間に適用可能な違いと同じです。

32
dawg

dict.items()はタプルのリストを返し、dict.iteritems()はTupleのイタレータオブジェクトを(key,value)として返します。タプルは同じですが、コンテナは異なります。

dict.items()は基本的に全ての辞書をリストにコピーします。次のコードを使用して、dict.items()dict.iteritems()の実行時間を比較してみてください。違いがわかります。

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer() #more memory intensive
for key,value in d.items():
    tmp = key + value #do something like print
t1 = timeit.default_timer() - start

start = timeit.default_timer()
for key,value in d.iteritems(): #less memory intensive
    tmp = key + value
t2 = timeit.default_timer() - start

私のマシンで出力する:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186

これはdictionary.iteritems()がはるかに効率的であることを明確に示しています。

13
Prabhu

あなたが持っている場合

dict = {key1:value1, key2:value2, key3:value3,...}

Python 2 では、dict.items()は各タプルをコピーし、タプルのリストを辞書、つまり[(key1,value1), (key2,value2), ...]で返します。つまり、辞書全体がタプルを含む新しいリストにコピーされるということです。

dict = {i: i * 2 for i in xrange(10000000)}  
# Slow and memory hungry.
for key, value in dict.items():
    print(key,":",value)

dict.iteritems()は辞書アイテムのイテレータを返します。返されるアイテムの値も同じ、つまり(key1,value1), (key2,value2), ...ですが、これはリストではありません。これは辞書アイテムのイテレータオブジェクトです。つまり、メモリ使用量が少なくなります(50%減)。

  • 可変スナップショットとしてリストします。d.items() -> list(d.items())
  • イテレータオブジェクト:d.iteritems() -> iter(d.items())

タプルは同じです。それぞれのタプルを比較したので、同じ結果になります。

dict = {i: i * 2 for i in xrange(10000000)}  
# More memory efficient.
for key, value in dict.iteritems():
    print(key,":",value)

Python 3 では、dict.items()はイテレータオブジェクトを返します。 dict.iteritems()が削除されたため、これ以上問題はありません。

4
Hary Bakta

dict.iteritems():あなたにイテレータを与えます。ループの外側の他のパタ​​ーンでイテレータを使用することができます。

student = {"name": "Daniel", "student_id": 2222}

for key,value in student.items():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

for key,value in student.iteritems():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

studentIterator = student.iteritems()

print(studentIterator.next())
('student_id', 2222)

print(studentIterator.next())
('name', 'Daniel')
0
ethplumber

Python 2と3の両方で動作する辞書の項目ペアを反復する方法が必要な場合は、次のようにしてください。

DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))

このように使用してください。

for key, value in DICT_ITER_ITEMS(myDict):
    # Do something with 'key' and/or 'value'.
0
R. Navega

Python3.xではdict.iteritemsがなくなったので、iter(dict.iitems())を使用して同じ出力とメモリ割り当てを取得します。

0
Dheeraj M Pai