Python2에서 dict.items ()와 dict.iteritems ()의 차이점은 무엇입니까?


704

dict.items()와 사이에 적용 가능한 차이점이 dict.iteritems()있습니까?

로부터 파이썬 문서 :

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

41
기본적으로 계산 방법의 차이입니다. items()한 번에 항목을 작성하고 목록을 리턴합니다. iteritems()제너레이터를 반환합니다. 제너레이터 next()는 호출 될 때마다 한 번에 하나의 항목을 "생성"하는 객체입니다 .
Joel Cornett

9
특정 경우 d[k] is v파이썬은 -5에서 256 사이의 모든 정수에 대해 정수 객체 배열을 유지하므로 항상 True를 반환합니다. docs.python.org/2/c-api/int.html 해당 범위에서 int를 만들면 : 실제로 단지 기존 개체에 대한 참조를 다시 얻을 >> a = 2; b = 2 >> a is b True하지만>> a = 1234567890; b = 1234567890 >> a is b False
t_tia

3
@ the_wolf 나는 당신이 질문에서 언급 한 문서의 파이썬 버전을 추가하는 것이 더 좋을 것이라고 생각합니다.
Lorenzo Belli

2
Python 3에서로 iteritems()변경 되었습니까 iter()? 위의 문서 링크가이 답변과 일치하지 않는 것 같습니다.
Gabriel Staples

3
정확히는 @GabrielStaples입니다. iteritems ()는 사전 Python 3에서 제거되며 대체되지 않습니다. 그러나 동일한 효과를 위해 iter ()를 사용합니다. 예를 들어 iter (dict.items ()). pep 469 참조 : python.org/dev/peps/pep-0469
Zim

답변:


862

그것은 진화의 일부입니다.

원래 Python items()은 실제 튜플 목록을 작성하여 반환했습니다. 잠재적으로 많은 추가 메모리가 필요할 수 있습니다.

그런 다음 생성기를 일반적으로 언어에 도입하고 해당 메소드를라는 이름의 반복자 생성기 메소드로 다시 구현했습니다 iteritems(). 이전 버전과의 호환성을 위해 원본이 남아 있습니다.

Python 3의 변경 사항 중 하나는 items()이제 반복자를 반환하며 목록이 완전히 작성되지 않는다는 것입니다. iteritems()방법은 또한 이후, 사라 items()세 작품처럼 파이썬으로 viewitems()파이썬 2.7.


159
진화의 한 단계를 놓쳤다는 점에 유의하십시오. Py3 동작은와 다릅니다 iteritems(). 실제로 dict에 대한 변경 사항을 반영하는 전체 시퀀스 프로토콜 객체를 만듭니다 (이중화 목록이 아닌 dict 자체에 의해 지원됨)-로 2.7로 백 포트되었습니다 viewitems().
lvc

3
이것에 대해 더 자세히 배우고 싶지만 내 google-fu가 실패합니다. 누군가 나를 더 잘 이해할 수 있도록 문서, 기사 또는 출처를 알려줄 수 있습니까? @lvc?
스튜

10
변경 사항이 설명되어 @Stew PEP (3106) 과 조금 더에이 파이썬 3.0의 새로운 기능
Tadhg 맥도날드 - 젠슨

1
이 고대 질문에 대해 자세히 설명해 주셔서 죄송하지만 Python 2.x에서 iteritems()항상 선호items() 되는 것을 올바르게 이해하고 있습니까?
RubenGeert

2
@RubenGeert 대부분의 시간은 중요하지 않습니다. 정말로 큰 dicts의 경우 바람직 할 수 있습니다.
키이스

95

dict.items()2 튜플 ( [(key, value), (key, value), ...]) 목록을 반환하는 반면 dict.iteritems()2 튜플을 생성하는 생성기입니다. 전자는 처음에는 더 많은 공간과 시간이 필요하지만 각 요소에 액세스하는 것은 빠르지 만 두 번째는 처음에는 더 적은 공간과 시간이 걸리지 만 각 요소를 생성하는 데 약간의 시간이 더 걸립니다.


9
왜 그것들이 다를 것으로 기대하겠습니까?
Ignacio Vazquez-Abrams가

3
문서의 "복사"는 요소가 복사 된 것을 의미하지는 않습니다 (원한다면을 사용하십시오 copy.deepcopy). 그것은 사전 항목의 복사본 것을 의미 : 당신이 경우에 items = dct.items()다음 수정 dct/ 추가 키를 삭제하거나하여 dct[k] = other_v, items동일하게 유지됩니다.
Dougal

4
명시 적으로 문서화되지 않은 한 파이썬의 어떤 것도 깊은 사본이 아닙니다.
Karl Knechtel

1
@ IgnacioVazquez-Abrams- "더 많은 공간과 시간"에 관하여 : 사전의 크기가 중요하기 시작합니다. {1:'one', 2:'two', ... }웹 서버에서 반복하고 결과를 렌더링하려는 "대형"사전 을 가정 해 보겠습니다. 파이썬 2.7 .items()과 비교 하여 어떤 규모로 걱정해야 .iteritems()합니까?
사용자

1
@buffer : 확실하지 않습니다. 내 예상치는 15-20 개 항목이지만 테스트하지는 않았습니다.
Ignacio Vazquez-Abrams

64

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에서 물건에만 있기 때문에, 더 깨끗하고 dict.items(), dict.keys()그리고 dict.values()반환되는 사용 가능한 뷰 객체를 그대로 dict.viewitems()Py2.x했던있다.

그러나

@lvc가 언급 한 것처럼, 뷰 객체는 동일하지 않습니다 반복자 당신이 반환하려는 경우 그래서, 반복자 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'>

34

'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!

따라서 품목 자체는 동일합니다. 품목을 운반하는 컨테이너가 다릅니다. 하나는리스트이고 다른 하나는 파이썬 버전에 따라 반복자입니다.

따라서 dict.items ()와 dict.iteritems ()의 적용 가능한 차이점은 목록과 반복자의 적용 가능한 차이점과 동일합니다.


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()훨씬 더 효율적 임을 보여줍니다 .


4

당신이 가지고 있다면

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

에서 파이썬 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)

에서 파이썬 3 , dict.items()반환 객체를 반복자. dict.iteritems ()가 제거되어 더 이상 문제가 없습니다.


4

dict.iteritemsPython3.x에서 사라 졌으므로 iter(dict.items())동일한 출력 및 메모리 할당을 얻는 데 사용 하십시오.


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'.

0

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')

-5

파이썬 2의 dict.iteritems ()는 파이썬 3의 dict.items ()와 같습니다.


2
이것은 올바르지 않습니다. 차이점은 이전 답변에서 이미 설명했습니다.
vaultah
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.