2012-08-15 2 views
3

age 및 room_number 특성을 가진 Person 개체 목록이 있고 person.age() 및 person.room_number()가 만족 스러우면 true를 반환하는 check() 함수를 작성했다고 가정합니다. 그렇지 않으면 false를 반환합니다. .Python, 객체 목록 필터링, 특정 속성을 반환 하시겠습니까?

filter(check, list_of_people_objects) 목록을 반복하지 않고 승인 된 각 사람의 방 번호의 목록을 반환하는 방법이처럼 두 번이, 내 질문은, 그러나 check()

의 기준을 만족하는 사람 개체 목록을 반환 목록 이해력을 사용하지 않고? 필터링을 수행하지만 iterable의보다 구체적인 속성을 반환합니다.

map(lambda x: x.room_number(), filter(check, list_of_people_objects))

답변

10

사실 가지 방법이 있습니다.

itertools

  1. map(..., itertools.ifilter(..)) 
    
  2. 목록 이해는 대부분 취향의 문제입니다 선택하지만 규칙은 후자쪽으로 기울어

    [x.room_number() for x in people if check(x)] 
    

.

+0

감사합니다. ifilter와 필터를 사용하는 데 차이가 있습니까? 나는리스트의 이해력이 (질문에 명시된대로) 작동한다는 것을 알고 있지만 itertools/map/filter를 사용하여 똑똑한 방법을 원한다. 하나의 반복만을 사용한다. D : – zhuyxn

+1

'ifilter()'는 시퀀스 대신 generator를 반환한다. 반복 할 때까지는 아무 것도 실제로 검사되지 않습니다. –

0
class Person(): 
    def __init__(self,age,room): 
     self.age=age 
     self.room=room 
    def check(self) : 
     if self.room>300 and self.age>15: 
      return True 
     else: 
      return False 

출력 : 당신이 값의 제한된 동일하고 어떤 옵션을 수행하는 속성의 부분 집합의 포함 조합을 수행 할 객체 필터링의 경우

>>> a=Person(20,285) 
>>> b=Person(22,990) 
>>> c=Person(12,958) 
>>> d=Person(18,150) 
>>> room=[] 
>>> filterd=[] 
>>> for x in (a,b,c,d): 
    if x.check(): 
     room.append(x.room) 
     filterd.append(x) 


>>> room 
[990] 
>>> filterd 
[<__main__.Person object at 0xa94c94c>] 
1

(필터링 된리스트의리스트를 포함하여) 당신은 생성자를 사용하여 다음을 할 수 있습니다. (코드의 마지막 줄, 나머지는 생성자 params를 생성하기 위해 행렬 곱셈을 사용하여 객체의 큰 목록을 생성하는 명령을 나타냅니다.)

#!/usr/bin/env python 
import itertools 
import pprint 
class myObj(object): 
    attr_1 = None 
    attr_2 = None 
    attr_3 = None 
    def __init__(self, at1, at2, at3): 
     self.attr_1 = at1 
     self.attr_2 = at2 
     self.attr_3 = at3 
     super(myObj, self).__init__() 

    def __repr__(self): 
     return '<%s %s>' % (type(self), pprint.pformat(self.__dict__)) 

objs = itertools.starmap(myObj, itertools.product(iter('val_%d' % (i) for i in 
    range(1,4)), repeat=3)) 

filter_dict = { 
    'attr_1' : 'val_1', 
    'attr_2' : 'val_2', 
    'attr_3' : 'val_3', 
} 
print(list(result.attr_3 for result in objs if not list(False for pn,cval in 
    filter_dict.items() if getattr(result, pn, None) != cval)))