2012-08-15 95 views
3

假设我有Person对象,其中有一个年龄和room_number属性的列表,我已经写了检查()函数,该函数返回True,如果person.age()和person.room_number()是令人满意的,否则返回False 。Python,过滤一个对象列表,但返回一个特定的属性?

filter(check, list_of_people_objects)将返回Person对象的列表,它满足check()

的标准然而,我的问题是,是否有返回每个批准人的房间号的列表,而无需通过列表迭代的方式两次,像所以没有使用列表理解? 因此过滤,但返回可迭代的更具体的属性。

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

回答

10

其实有方式。

  1. itertools

    map(..., itertools.ifilter(..)) 
    
  2. 列表理解

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

你的选择主要是口味的问题,但会议对后者倾斜。

+0

谢谢,使用ifilter和过滤器有什么区别吗?我知道列表理解将会起作用(正如问题中指定的那样),但是希望使用itertools/map/filter的一个聪明方法,它只使用一次迭代D: – zhuyxn 2012-08-15 09:41:53

+1

'ifilter()'返回一个生成器而不是一个序列,所以在迭代完成之前没有任何内容被检查。 – 2012-08-15 09:49:08

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))) 
相关问题