Python, фильтрует список объектов, но возвращает определенный атрибут?

Предположим, у меня есть список объектов Person, которые имеют атрибут age и room_number, и я написал функцию check (), которая возвращает True, если person.age () и person.room_number () являются удовлетворительными, и False в противном случае.

filter(check, list_of_people_objects) вернет список объектов Person, которые удовлетворяют критериям check()

Однако у меня вопрос: есть ли способ вернуть список номеров комнат каждого утвержденного человека без повторения списка дважды, например, без использования понимания списка? Итак, фильтрация, но возвращающая более конкретный атрибут итерации.

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


person zhuyxn    schedule 15.08.2012    source источник


Ответы (3)


На самом деле есть два способа.

  1. itertools

    map(..., itertools.ifilter(..))
    
  2. Понимание списка

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

Что вы выберете - это в основном дело вкуса, но условности склоняются к последнему.

person Ignacio Vazquez-Abrams    schedule 15.08.2012
comment
Спасибо, а есть ли разница между использованием ifilter и filter? Я знаю, что понимание списка будет работать (как указано в вопросе), но надеялся на умный способ с itertools / map / filter, который будет использовать только одну итерацию D: - person zhuyxn; 15.08.2012
comment
ifilter() возвращает генератор вместо последовательности, поэтому на самом деле ничего не проверяется, пока не будет повторена итерация. - person Ignacio Vazquez-Abrams; 15.08.2012

В случае фильтрации объектов, когда вы хотите выполнить инклюзивное объединение подмножества свойств, чтобы равняться ограниченному набору значений, а затем выполнить любую опцию (включая список значений атрибутов) отфильтрованного списка, вы можете сделать следующее, используя генераторы в один оператор (последняя строка кода, остальное предназначено для инструкции, показывающей создание большого списка объектов с использованием умножения матриц для генерации параметров конструктора)

#!/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)))
person SkyLeach    schedule 29.01.2016

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>]
person Ashwini Chaudhary    schedule 15.08.2012