Python 사전이 d
있고 다음과 같이 반복 한다고 가정 해 보겠습니다 .
for k,v in d.iteritems():
del d[f(k)] # remove some item
d[g(k)] = v # add a new item
( f
그리고 g
일부 블랙 박스 변환입니다.)
즉,을 d
사용하여 반복 하는 동안 항목을 추가 / 제거하려고합니다 iteritems
.
잘 정의되어 있습니까? 답변을 뒷받침 할 참고 자료를 제공해 주시겠습니까?
(깨진 경우이 문제를 해결하는 방법은 매우 분명하므로 이것은 내가 추구하는 각도가 아닙니다.)
답변
Python 문서 페이지 ( Python 2.7 용 ) 에 명시 적으로 언급되어 있습니다.
iteritems()
사전에 항목을 추가하거나 삭제하는 동안 사용하면 a가 발생RuntimeError
하거나 모든 항목을 반복하지 못할 수 있습니다.
Python 3과 유사합니다 .
iter(d)
, d.iterkeys()
및 에도 동일 d.itervalues()
하게 적용됩니다.for k, v in d.items():
(내가 정확히 기억하지 못하는 for
구현 호출하면 않지만, 나는 놀라지 않을 것이다 iter(d)
).
답변
Alex Martelli가 여기 에 무게를두고 있습니다. .
컨테이너를 반복하는 동안 컨테이너 (예 : dict)를 변경하는 것은 안전하지 않을 수 있습니다. 따라서 del d[f(k)]
안전하지 않을 수 있습니다. 아시다시피 해결 방법은 d.items()
대신 사용하는 것입니다 (컨테이너의 독립적 인 복사본을 반복 하기 위해 ).d.iteritems()
동일한 기본 컨테이너를 사용하는 ( 사용하는 것입니다.
dict 의 기존 인덱스 에서 값을 수정하는 것은 괜찮지 만 새 인덱스 (예 :)에 값을 삽입하면 d[g(k)]=v
작동하지 않을 수 있습니다.
답변
적어도 d.iteritems()
. 나는 그것을 시도했지만 Python이 실패합니다.
RuntimeError: dictionary changed size during iteration
대신을 사용 d.items()
하면 작동합니다.
Python 3에서는 Python 2 d.items()
와 같이 사전에 대한보기 d.iteritems()
입니다. Python 3에서이 작업을 수행하려면 대신 d.copy().items()
. 이것은 우리가 반복하는 데이터 구조의 수정을 피하기 위해 딕셔너리의 복사본을 반복 할 수있게합니다.
답변
나는 Numpy 배열을 포함하는 큰 사전을 가지고 있으므로 @ murgatroid99가 제안한 dict.copy (). keys () 것은 실현 가능하지 않았습니다 (작동했지만). 대신 keys_view를 목록으로 변환했고 제대로 작동했습니다 (Python 3.4에서).
for item in list(dict_d.keys()):
temp = dict_d.pop(item)
dict_d['some_key'] = 1 # Some value
나는 이것이 위의 답변과 같은 Python의 내부 작동의 철학적 영역으로 뛰어 들지 않는다는 것을 알고 있지만 명시된 문제에 대한 실질적인 해결책을 제공합니다.
답변
다음 코드는 이것이 잘 정의되지 않았 음을 보여줍니다.
def f(x):
return x
def g(x):
return x+1
def h(x):
return x+10
try:
d = {1:"a", 2:"b", 3:"c"}
for k, v in d.iteritems():
del d[f(k)]
d[g(k)] = v+"x"
print d
except Exception as e:
print "Exception:", e
try:
d = {1:"a", 2:"b", 3:"c"}
for k, v in d.iteritems():
del d[f(k)]
d[h(k)] = v+"x"
print d
except Exception as e:
print "Exception:", e
첫 번째 예제는 g (k)를 호출하고 예외를 발생시킵니다 (반복 중에 사전 변경된 크기).
두 번째 예제는 h (k)를 호출하고 예외를 발생시키지 않지만 다음을 출력합니다.
{21: 'axx', 22: 'bxx', 23: 'cxx'}
코드를 보면 잘못된 것 같습니다. 다음과 같은 것을 예상했을 것입니다.
{11: 'ax', 12: 'bx', 13: 'cx'}
답변
나는 같은 문제가 있었고 다음 절차를 사용 하여이 문제를 해결했습니다.
Python List는 반복하는 동안 수정하더라도 반복 될 수 있습니다. 따라서 다음 코드의 경우 1을 무한대로 인쇄합니다.
for i in list:
list.append(1)
print 1
따라서 목록과 사전을 함께 사용하면이 문제를 해결할 수 있습니다.
d_list=[]
d_dict = {}
for k in d_list:
if d_dict[k] is not -1:
d_dict[f(k)] = -1 # rather than deleting it mark it with -1 or other value to specify that it will be not considered further(deleted)
d_dict[g(k)] = v # add a new item
d_list.append(g(k))
답변
Python 3에서는 다음을 수행해야합니다.
prefix = 'item_'
t = {'f1': 'ffw', 'f2': 'fca'}
t2 = dict()
for k,v in t.items():
t2[k] = prefix + v
또는 다음을 사용하십시오.
t2 = t1.copy()
원본 사전을 수정해서는 안되며, 잠재적 인 버그 또는 RunTimeErrors뿐만 아니라 혼란을 야기합니다. 새 키 이름으로 사전에 추가하지 않는 한.