假设我有一个Person对象列表,它有age和room_number属性,我写了一个check()函数,如果person.age()和person.room_number()是满意的,则返回True,False否则。
filter(check, list_of_people_objects)
将返回满足check()
然而,我的问题是,是否有一种方法可以返回每个已批准人员的房间号码列表,而无需重复列表两次,如果没有使用列表理解? 所以过滤,但返回可迭代的更具体的属性。
map(lambda x: x.room_number(), filter(check, list_of_people_objects))
答案 0 :(得分:11)
实际上有两种方式。
map(..., itertools.ifilter(..))
列表理解
[x.room_number() for x in people if check(x)]
你选择的主要是品味问题,但会议倾向于后者。
答案 1 :(得分:1)
在对象过滤的情况下,您希望将属性子集的包含性并集等同于一组有限的值,然后执行已过滤列表的任何选项(包括列出属性值),您可以执行以下操作在单个语句中使用生成器(最后一行代码,其余部分用于显示使用矩阵乘法生成大型对象列表以生成构造函数参数的指令)
#!/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)))
答案 2 :(得分: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>]