754

と の間に適用可能な違いは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
4

10 に答える 10

919

それは進化の一部です。

もともと、Pythonitems()はタプルの実際のリストを作成し、それを返しました。これにより、多くの余分なメモリが必要になる可能性があります。

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

Python 3 の変更点の 1 つは、 items()ビューを返すようになったことであり、alistが完全にビルドされることはありません。Python 3では Python 2.7 のように動作するiteritems()ため、メソッドもなくなりました。items()viewitems()

于 2012-05-05T03:26:27.157 に答える
103

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

于 2012-05-05T03:00:52.600 に答える
73

Py2.x で

コマンドdict.items()dict.keys()およびは、ディクショナリのキーと値のペアのリストのコピー返しdict.values()ます。コピーされたリストが非常に大きい場合、これには大量のメモリが必要になる可能性があります。(k, v)

コマンド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 では、Py2.x と同じようにビュー オブジェクトを返すとavailableしかないため、よりクリーンdict.items()です。dict.keys()dict.values()dict.viewitems()

しかし

@lvc が指摘したように、ビュー オブジェクトはiteratorと同じではないため、Py3.x でイテレータを返したい場合は、次を使用できます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'>
于 2013-12-02T13:33:29.677 に答える
35

あなたは尋ねました:「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() はスライス可能ではありません:

>>> 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() の間の適用可能な違いは、リストと反復子の間の適用可能な違いと同じです。

于 2012-05-05T06:29:57.203 に答える
15

dict.items()タプルのリストをdict.iteritems()返し、ディクショナリ内のタプルの反復子オブジェクトを として返します(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()これは、はるかに効率的であることを明確に示しています。

于 2016-09-11T02:26:01.923 に答える
4

あなたが持っている場合

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() が削除されたため、これ以上の問題はありません。

于 2016-09-11T01:37:43.510 に答える
1

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'.
于 2018-10-07T22:54:59.633 に答える