development

특정 키만 포함하도록 필터 dict?

big-blog 2020. 2. 20. 23:32
반응형

특정 키만 포함하도록 필터 dict?


나는 dict많은 항목을 가지고 있습니다. 나는 그들 중 일부에만 관심이 있습니다. 다른 모든 것을 정리하는 쉬운 방법이 있습니까?


새로운 dict 구성하기 :

dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }

사전 이해력을 사용합니다.

부족한 버전 (예 : Python 2.6 이하)을 사용하는 경우 만드십시오 dict((your_key, old_dict[your_key]) for ...). 더 나쁘지만 동일합니다.

이것은 jnnnnn의 버전과 달리 old_dict모든 크기의 안정적인 성능 (your_keys 수에 따라 다름)을 갖습니다 . 속도와 메모리면에서 모두. 이것은 생성자 표현식이므로 한 번에 하나의 항목을 처리하며 old_dict의 모든 항목을 살펴 보지는 않습니다.

전체 위치 제거 :

unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]

약간 더 우아한 받아쓰기 이해 :

foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}

다음은 Python 2.6의 예입니다.

>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}

필터링 부분이 if문입니다.

이 방법은 매우 많은 키 중 몇 개만 선택하려는 경우 delnan의 답변보다 느립니다.


funcy 라이브러리의 프로젝트 기능으로 그렇게 할 수 있습니다 .

from funcy import project
small_dict = project(big_dict, keys)

select_keys도 살펴 보십시오 .


코드 1 :

dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
    if key % 2 == 0:
        d1[key] = value

코드 2 :

dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}

코드 3 :

dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}

모든 코드 조각 성능은 number = 1000을 사용하여 timeit로 측정되며 각 코드 조각마다 1000 번 수집됩니다.

여기에 이미지 설명을 입력하십시오

python 3.6의 경우 세 가지 방법의 필터 dict 키 성능이 거의 동일합니다. 파이썬 2.7 코드 3의 경우 약간 빠릅니다.


이 하나의 라이너 람다는 작동해야합니다.

dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])

예를 들면 다음과 같습니다.

my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")

# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}

그것은 dict 키 (i에서 x)를 반복하는 기본 목록 이해이며 키가 원하는 키 목록 (y)에 있으면 튜플 (키, 값) 쌍 목록을 출력합니다. dict ()는 전체를 감싸서 dict 객체로 출력합니다.


원래 사전 orig과 관심있는 항목 세트가 제공됩니다 keys.

filtered = dict(zip(keys, [orig[k] for k in keys]))

delnan의 답변만큼 좋지는 않지만 관심있는 모든 Python 버전에서 작동해야합니다. 그러나 keys원래 사전 존재 하는 각 요소에는 취약합니다 .


delnan이 수락 한 답변을 바탕으로합니다.

원하는 키 중 하나가 old_dict에 없으면 어떻게합니까? delnan 솔루션은 포착 할 수있는 KeyError 예외를 발생시킵니다. 그것이 당신이 필요로하지 않는 경우 :

  1. old_dict와 want_keys 세트 모두에 존재하는 키만 포함하십시오.

    old_dict = {'name':"Foobar", 'baz':42}
    wanted_keys = ['name', 'age']
    new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
    
    >>> new_dict
    {'name': 'Foobar'}
    
  2. old_dict에 설정되지 않은 키의 기본값이 있습니다.

    default = None
    new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
    
    >>> new_dict
    {'age': None, 'name': 'Foobar'}
    

이 함수는 트릭을 수행합니다.

def include_keys(dictionary, keys):
    """Filters a dict by only including certain keys."""
    key_set = set(keys) & set(dictionary.keys())
    return {key: dictionary[key] for key in key_set}

delnan의 버전과 마찬가지로,이 버전은 사전 이해를 사용하며 큰 사전에 안정적인 성능을 제공합니다 (사전의 총 키 수가 아니라 허용하는 키 수에만 의존 함).

MyGGan의 버전과 마찬가지로이 키를 사용하면 키 목록에 사전에없는 키가 포함될 수 있습니다.

그리고 보너스로, 다음은 원본에서 특정 키를 제외하여 사전을 만들 수있는 역입니다.

def exclude_keys(dictionary, keys):
    """Filters a dict by excluding certain keys."""
    key_set = set(dictionary.keys()) - set(keys)
    return {key: dictionary[key] for key in key_set}

delnan의 버전과 달리 작업이 제대로 수행되지 않으므로 성능은 사전의 키 수와 관련이 있습니다. 그러나 이것의 장점은 함수가 제공된 사전을 수정하지 않는다는 것입니다.

편집 : dict에서 특정 키를 제외시키는 별도의 기능이 추가되었습니다.


다른 옵션 :

content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())

그러나 list() 가 아닌 (Python 2) 또는 iterator (Python 3)가 반환 filter()합니다 dict.


짧은 형식:

[s.pop(k) for k in list(s.keys()) if k not in keep]

간결성을 유지하기 위해 대부분의 답변에서 알 수 있듯이 a list또는로 복제 객체를 만들어야합니다 dict. 이것은 버림을 생성 list하지만 original의 키를 삭제합니다 dict.


선택한 키를 제거한 상태로 새 사전을 만들려면 사전 이해
사용할 수 있습니다 . 예를 들면 다음과 같습니다.

d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}

del하나의 라이너에서 사용하는 또 다른 간단한 방법이 있습니다 .

for key in e_keys: del your_dict[key]

e_keys제외 할 키 목록입니다. 그것은 당신에게 새로운 것을주지 않고 당신의 받아쓰기를 업데이트 할 것입니다.

새로운 출력 dict을 원한다면 삭제하기 전에 dict의 사본을 만드십시오.

new_dict = your_dict.copy()           #Making copy of dict

for key in e_keys: del new_dict[key]

참고 URL : https://stackoverflow.com/questions/3420122/filter-dict-to-contain-only-certain-keys



반응형