티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
How do I delete items from a dictionary while iterating over it?
파이썬에서 딕셔너리를 반복하면서 항목을 삭제하는 방법은 무엇인가요?
문제 내용
Can I delete items from a dictionary in Python while iterating over it?
파이썬 딕셔너리에서 항목을 반복하면서 삭제할 수 있습니까?
I want to remove elements that don't meet a certain condition from the dictionary, instead of creating an entirely new dictionary. Is the following a good solution, or are there better ways?
파이썬에서 딕셔너리를 반복하면서 해당 조건을 충족하지 않는 요소를 삭제하려고 합니다. 새로운 딕셔너리를 만드는 대신 기존 딕셔너리에서 요소를 제거하는 것이 목적입니다. 다음은 좋은 방법인가요, 아니면 더 나은 방법이 있나요?
for k, v in mydict.items():
if k == val:
del mydict[k]
높은 점수를 받은 Solution
For Python 3+:
Python 3+ 용:
>>> mydict
{'four': 4, 'three': 3, 'one': 1}
>>> for k in list(mydict.keys()):
... if mydict[k] == 3:
... del mydict[k]
>>> mydict
{'four': 4, 'one': 1}
The other answers work fine with Python 2 but raise a RuntimeError
for Python 3:
다른 답변들은 Python 2에서 잘 작동하지만 Python 3에서 RuntimeError를 일으킵니다:
RuntimeError: dictionary changed size during iteration.
런타임 오류: 반복하는 동안 사전 크기가 변경되었습니다.
This happens because mydict.keys()
returns an iterator not a list. As pointed out in comments simply convert mydict.keys()
to a list by list(mydict.keys())
and it should work.
이는 mydict.keys()가 리스트가 아닌 반복자를 반환하기 때문에 발생합니다. 댓글에서 언급한대로, list(mydict.keys())로 mydict.keys()를 목록으로 변환하면 작동합니다.
For Python 2:
Python 2 용:
A simple test in the console shows you cannot modify a dictionary while iterating over it:
다음과 같은 간단한 테스트를 통해 딕셔너리를 반복하는 동안 딕셔너리를 수정할 수 없다는 것을 알 수 있습니다.
>>> mydict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> for k, v in mydict.iteritems():
... if k == 'two':
... del mydict[k]
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
As stated in delnan's answer, deleting entries causes problems when the iterator tries to move onto the next entry. Instead, use the keys()
method to get a list of the keys and work with that:
delnan의 답변에서 언급한대로 항목을 삭제하면 반복자가 다음 항목으로 이동할 때 문제가 발생합니다. 대신 keys() 메소드를 사용하여 키의 목록을 가져와 해당 목록으로 작업하면 됩니다.
>>> for k in mydict.keys():
... if k == 'two':
... del mydict[k]
>>> mydict
{'four': 4, 'three': 3, 'one': 1}
If you need to delete based on the items value, use the items()
method instead:
값에 따라 삭제해야하는 경우 items() 메소드를 대신 사용하세요.
>>> for k, v in mydict.items():
... if v == 3:
... del mydict[k]
>>> mydict
{'four': 4, 'one': 1}
가장 최근 달린 Solution
There is a way that may be suitable if the items you want to delete are always at the "beginning" of the dict iteration
딕셔너리에서 삭제해야 할 항목이 항상 dict 반복에서 "처음"에 있으면 적합한 방법이 있습니다.
while mydict:
key, value = next(iter(mydict.items()))
if should_delete(key, value):
del mydict[key]
else:
break
The "beginning" is only guaranteed to be consistent for certain Python versions/implementations. For example from What’s New In Python 3.7
"처음"은 특정 Python 버전/구현에 대해서만 일관성이 보장됩니다. 예를 들어, Python 3.7의 What's New에서는 다음과 같이 언급됩니다.
the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec.
dict 객체의 삽입 순서 보존 속성이 Python 언어 사양의 공식 부분으로 선언되었습니다.
This way avoids a copy of the dict that a lot of the other answers suggest, at least in Python 3.
이 방법은 Python 3에서는 딕셔너리를 복사하는 것을 권장하는 다른 답변과는 달리 딕셔너리의 복사를 피할 수 있습니다.
출처 : https://stackoverflow.com/questions/5384914/how-do-i-delete-items-from-a-dictionary-while-iterating-over-it
'개발 > 파이썬' 카테고리의 다른 글
두 값 사이에 있는 숫자로 이루어진 리스트 만들기 (0) | 2023.02.13 |
---|---|
파이썬 딕셔너리를 문자열로 변환하고 다시 되돌리는 방법 (0) | 2023.02.13 |
훈련된 Keras 모델을 로드하고 계속 학습시키기 (0) | 2023.02.12 |
Pandas의 조건부 시리즈/데이터프레임 열 생성 (0) | 2023.02.11 |
리스트에서 요소의 모든 등장 위치(인덱스) 찾는 방법 (0) | 2023.02.11 |