как выбрать объект из списка объектов по его атрибутов в Python

извинения, если этот вопрос уже задан, но я не думаю, что знаю правильную терминологию для поиска соответствующего решения через google.

Я хотел бы выбрать объект из списка объектов по значению его атрибута, например:

class Example():
    def __init__(self):
        self.pList = []
    def addPerson(self,name,number):
        self.pList.append(Person(self,name,number))

class Person():
    def __init__(self,name,number):
        self.nom = name
        self.num = number


a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)

a.pList #.... somehow select dave by giving the value 123

в моем случае номер всегда будет уникальным

Спасибо за помощь

4 ответов


попробовать

dave = next(person for person in a.pList if person.num == 123)

или

for person in a.pList:
    if person.num == 123:
        break
else:
    print "Not found."
dave = person

вам нужна терминология "карта" или "словарь": это приведет вас к правая страница в Python doc.

очень простой пример:

>>> a = {123:'dave', 345:'mike'}
>>> a[123]
'dave'

если эти ном являются уникальными ключами, и все, что вы когда-либо собираетесь сделать, это доступ к вашим лицам, используя этот уникальный ключ, вы должны действительно использовать словарь.

однако, если вы хотите добавить больше атрибутов с течением времени, и если вы хотите иметь возможность получить один или несколько человек по любому из этих атрибутов, вы можете пойти с более сложным решением:

class Example():
    def __init__(self):
        self.__pList = []
    def addPerson(self,name,number):
        self.__pList.append(Person(name,number))
    def findPerson(self, **kwargs):
        return next(self.__iterPerson(**kwargs))
    def allPersons(self, **kwargs):
        return list(self.__iterPerson(**kwargs))
    def __iterPerson(self, **kwargs):
        return (person for person in self.__pList if person.match(**kwargs))

class Person():
    def __init__(self,name,number):
        self.nom = name
        self.num = number
    def __repr__(self):
        return "Person('%s', %d)" % (self.nom, self.num) 
    def match(self, **kwargs):
        return all(getattr(self, key) == val for (key, val) in kwargs.items())

Итак, предположим, у нас есть один Майк и два Дэйва

a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)
a.addPerson('dave',678)

теперь вы можете найти человека по номер:

>>> a.findPerson(num=345)
Person('mike', 345)

имя:

>>> a.allPersons(nom='dave')
[Person('dave', 123), Person('dave', 678)]

или так:

>>> a.findPerson(nom='dave', num=123)
Person('dave', 123)

отсутствующее подчеркивание делает plist общественная собственность. Я не думаю, что это то, что вы хотите, так как он не инкапсулирует функциональность, и вы можете вызвать a.plist.append вместо a.addPerson.

class Example():
   ...
   def filter(self, criteria):
       for p in self.plist:
           if criteria(p):
               yield p

   def getByNum(self, num):
        return self.filter(lambda p: p.num == num)

dave = next(a.getByNum(123))

Если числа уникальны, вы также можете использовать словарь, который отображает от числа к имени или лицу вместо списка. Но это зависит от вашей реализации.