키가 특정 문자열을 포함하는 파이썬 사전에서 항목 필터링


97

저는 파이썬으로 무언가를 개발하는 C 코더입니다. 나는 C에서 다음을 수행하는 방법을 알고 있지만 (따라서 파이썬에 적용된 C와 유사한 논리로) 그것을 수행하는 'Python'방식이 무엇인지 궁금합니다.

사전 d가 있고 항목의 하위 집합에 대해 작업하고 싶습니다. 키 (문자열)에만 특정 하위 문자열이 포함되어 있습니다.

즉, C 로직은 다음과 같습니다.

for key in d:
    if filter_string in key:
        # do something
    else
        # do nothing, continue

나는 파이썬 버전이 다음과 같을 것이라고 상상하고 있습니다.

filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
    # do something

여기에서 사전 필터링과 관련된 많은 게시물을 찾았지만 정확히 이것과 관련된 게시물을 찾을 수 없습니다.

내 사전이 중첩되지 않고 Python 2.7을 사용하고 있습니다.



답변:


188

방법에 대한 DICT 이해 :

filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}

보시다시피 영어처럼 잘 읽히기 때문에 자명해야합니다.

이 구문에는 Python 2.7 이상이 필요합니다.

단지 파이썬 3에서가 dict.items()아니라 iteritems()당신이 사용하는 것입니다 그래서 :

filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}

1
왜 안돼 filtered_dict = {k:d[k] for k in d if filter_string in k}?
thefourtheye 2014 년

5
@thefourtheye 나는 조회에 영향을 미치지 않기 때문에 내 것이 더 빠르다고 추측 할 것입니다 d[k].
Jonathon Reinhart 2014 년

또한 그는 # do something주석에서 말하지만 여기에 몇 가지 키를 놓습니다.
thefourtheye 2014 년

우리는이 있나요 iteritems파이썬 3에서? 나는 그렇게 생각하지 않는다. 그래서 내 버전은 호환 될 것입니다.
thefourtheye 2014 년

1
파이썬 3에서는 대체 할 iteritems함께 items파이썬 2.7의 같은 인 iteritems.
Jonathon Reinhart 2014 년

18

가장 읽기 쉽고 유지 관리가 쉬운 것을 선택하십시오. 한 줄로 적을 수 있다고해서 그렇게해야한다는 의미는 아닙니다. 기존 솔루션은 값 조회를 건너 뛰기 위해 iteritems를 사용하는 것 외에 내가 사용하는 것과 비슷하며 피할 수 있다면 중첩 된 ifs를 싫어합니다.

for key, val in d.iteritems():
    if filter_string not in key:
        continue
    # do something

그러나 필터링 된 dict를 반복 할 수있는 무언가를 정말로 원한다면 필터링 된 dict를 빌드하고 반복하는 두 단계 프로세스를 수행하지 않고 대신 생성기를 사용합니다. 발전기?

먼저 제너레이터를 만들고, 좋은 디자인은 재사용 할 수있을만큼 충분히 추상화해야합니다.

# The implementation of my generator may look vaguely familiar, no?
def filter_dict(d, filter_string):
    for key, val in d.iteritems():
        if filter_string not in key:
            continue
        yield key, val

그런 다음 생성기를 사용하여 간단하고 이해하기 쉬운 코드로 문제를 멋지고 깔끔하게 해결할 수 있습니다.

for key, val in filter_dict(d, some_string):
    # do something

간단히 말해서, 발전기는 굉장합니다.


11

내장 필터 기능 을 사용하여 특정 조건에 따라 사전, 목록 등을 필터링 할 수 있습니다 .

filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))

장점은 다른 데이터 구조에 사용할 수 있다는 것입니다.


주의 items:해야 item:람다 정의.
bkribbs

오류를 지적 해 주신 @bkribbs에게 감사드립니다. 지금 수정했습니다.
Pulkit

8
input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}

3
사용하는 방법 iteritems()items().
Jonathon Reinhart 2014 년

@Jonathin Reinhart 나는 그것에 대해 몰랐습니다. 감사.
jspurim

2
Python 2.7에서만. 파이썬 3에서는이 단지 items() 파이썬 2.7의 같은 역할을하는 iteritems.
Jonathon Reinhart 2014 년

1
질문은 python 2.7에 대한 것입니다
Brendan F

7

Jonathon은 그의 대답 에서 dict 이해를 사용하는 접근 방식을 제공 했습니다 . 다음은 무언가를하는 부분 을 다루는 접근 방식입니다 .

사전 값으로 무언가를하고 싶다면 사전 이해력이 전혀 필요하지 않습니다.

iteritems(질문에 태그를 지정 했으므로)를 사용 하고 있습니다.

results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])

이제 결과는 some_function키에있는 사전의 각 키 / 값 쌍에 적용된 목록에 있습니다 foo.

값을 처리하고 키를 무시하려면 목록 이해도를 변경하십시오.

results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])

some_function 호출 가능할 수 있으므로 람다도 작동합니다.

results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k])

생성기 표현식 을 매핑에 전달할 수 있으므로 내부 목록은 실제로 필요하지 않습니다 .

>>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
[4]

흥미 롭군요. some_function은 어떻게 정의됩니까? 첫 번째 경우 (k, v)에서 두 개의 매개 변수 만 사용합니까? 첫 번째 키 다음 값?
메모

네, 그냥 콜 러블입니다. 그래서 map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))-이것은 당신에게 줄 것 [4]입니다.
Burhan Khalid 2014 년

이것은 정확하지만 map목록 이해력을 사용 하는 것보다 비단뱀 적 입니다. [f(v) for k, v in d.iteritems() if substring in k]훨씬 더 읽기 쉽고 효율적이라고 생각합니다.
Davidmh

@memo 두 개의 매개 변수를 사용하지 않고 두 개의 요소가있는 단일 매개 변수를 사용합니다. 또한 두 개의 인수로 압축을 풀 수있는 스타 맵 도 있지만 지연 반복기입니다 (실행하기 전에 반복해야합니다, 즉 results = list(starmap(...))또는 for result in starmap(...): ...).
nmclean 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.