[python] dict에서 빈 문자열로 키를 제거하는 효율적인 방법

사전이 있고 빈 값 문자열이있는 모든 키를 제거하고 싶습니다.

metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
            u'EXIF:CFAPattern2': u''}

이를 수행하는 가장 좋은 방법은 무엇입니까?



답변

파이썬 2.X

dict((k, v) for k, v in metadata.iteritems() if v)

파이썬 2.7-3.X

{k: v for k, v in metadata.items() if v is not None}

모든 키에는 값이 있습니다. 그 값 중 일부는 빈 문자열입니다. 딕셔너리에 값이없는 키 같은 것은 없습니다. 값이 없다면 dict에 없을 것입니다.


답변

BrenBarn의 솔루션 보다 더 짧아 질 수 있습니다 (그리고 더 읽기 쉽습니다 )

{k: v for k, v in metadata.items() if v}

Python 2.7.3으로 테스트되었습니다.


답변

원래 사전을 수정해야하는 경우 :

empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
    del metadata[k]

딕셔너리를 반복하는 동안에는 딕셔너리를 수정할 수 없기 때문에 빈 키 목록을 만들어야합니다 (알다시피). 값이 비어있는 항목이 많은 경우를 제외하고는 새로운 사전을 만드는 것보다 비용이 적게 듭니다 (메모리 측면에서).


답변

BrenBarn의 솔루션 은 이상적입니다 (그리고 pythonic, 추가 할 수도 있습니다). 그러나 다음은 또 다른 (fp) 솔루션입니다.

from operator import itemgetter
dict(filter(itemgetter(1), metadata.items()))


답변

자주 중첩되고 주기도 포함 할 수있는 실제 데이터 구조를 처리하는 데 완전한 기능을 제공하면서도 간결한 접근 방식을 원한다면 boltons 유틸리티 패키지에서 remap 유틸리티를 살펴 보는 것이 좋습니다 .

iterutils.py 를 프로젝트에 pip install boltons복사 한 후 다음을 수행하십시오.

from boltons.iterutils import remap

drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)

이 페이지 에는 Github의 API에서 훨씬 더 큰 객체로 작업하는 예제를 포함하여 더 많은 예제가 있습니다.

순수 Python이므로 어디서나 작동하며 Python 2.7 및 3.3 이상에서 완전히 테스트되었습니다. 무엇보다 정확히 이와 같은 경우에 대해 작성 했으므로 처리되지 않는 경우를 발견하면 여기에서 바로 수정하도록 저를 괴롭힐 수 있습니다 .


답변

를 기반으로 라이언의 솔루션 , 당신은 또한 목록 및 중첩 된 사전이있는 경우 :

Python 2 :

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

Python 3 :

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d


답변

중첩 된 사전이 있고 빈 하위 요소에 대해서도 작동하도록하려면 BrenBarn의 제안에 대한 재귀 변형을 사용할 수 있습니다.

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d