임의의 조건 함수에 따라 사전을 필터링하는 방법은 무엇입니까? (‘c’, (5, 5)), (‘b’, (1, 2)), (‘d’,

포인트 사전이 있습니다.

>>> points={'a':(3,4), 'b':(1,2), 'c':(5,5), 'd':(3,3)}

x와 y 값이 5보다 작은 모든 점, 즉 ‘a’, ‘b’및 ‘d’와 같은 새 사전을 만들고 싶습니다.

에 따르면 각 사전에는 튜플 items()목록을 반환하는 함수 가 있습니다 (key, pair).

>>> points.items()
[('a', (3, 4)), ('c', (5, 5)), ('b', (1, 2)), ('d', (3, 3))]

그래서 나는 이것을 썼다 :

>>> for item in [i for i in points.items() if i[1][0]<5 and i[1][1]<5]:
...     points_small[item[0]]=item[1]
...
>>> points_small
{'a': (3, 4), 'b': (1, 2), 'd': (3, 3)}

더 우아한 방법이 있습니까? 파이썬이 매우 멋진 dictionary.filter(f)기능 을 가질 것으로 기대했습니다 …



답변

오늘날 Python 2.7 이상에서는 dict comprehension을 사용할 수 있습니다.

{k: v for k, v in points.iteritems() if v[0] < 5 and v[1] < 5}

그리고 파이썬 3에서 :

{k: v for k, v in points.items() if v[0] < 5 and v[1] < 5}

답변

dict((k, v) for k, v in points.items() if all(x < 5 for x in v))

당신은 전화를 선택할 수 .iteritems()대신 .items()파이썬 2 인 경우와 points있을 수 많은 항목을.

all(x < 5 for x in v)각 점이 항상 2D 만임을 확신하면 과잉 일 수 있지만 (이 경우 and)로 동일한 구속 조건을 나타낼 수는 있지만 잘 작동합니다 .-).


답변

points_small = dict(filter(lambda (a,(b,c)): b<5 and c < 5, points.items()))

답변

>>> points = {'a': (3, 4), 'c': (5, 5), 'b': (1, 2), 'd': (3, 3)}
>>> dict(filter(lambda x: (x[1][0], x[1][1]) < (5, 5), points.items()))

{'a': (3, 4), 'b': (1, 2), 'd': (3, 3)}

답변

dict((k, v) for (k, v) in points.iteritems() if v[0] < 5 and v[1] < 5)

답변

Alex Martelli의 대답은 분명히이 작업을 수행하는 가장 우아한 방법이라고 생각하지만 dictionary.filter(f)파이썬 방식 으로 슈퍼 멋진 방법에 대한 귀하의 요구를 충족시키는 방법을 추가하고 싶었습니다 .

class FilterDict(dict):
    def __init__(self, input_dict):
        for key, value in input_dict.iteritems():
            self[key] = value
    def filter(self, criteria):
        for key, value in self.items():
            if (criteria(value)):
                self.pop(key)

my_dict = FilterDict( {'a':(3,4), 'b':(1,2), 'c':(5,5), 'd':(3,3)} )
my_dict.filter(lambda x: x[0] < 5 and x[1] < 5)

기본적으로 우리는에서 상속 dict하지만 필터 메소드를 추가 하는 클래스를 만듭니다 . 파괴적으로 반복 .items()하는 .iteritems()동안 사용 하면 예외가 발생하기 때문에 필터링 에 사용해야 합니다 .