как выбрать объект из списка объектов по его атрибуту в python - PullRequest
9 голосов
/ 03 марта 2011

Извините, если этот вопрос уже задавался, но я не думаю, что знаю правильную терминологию для поиска подходящего решения через 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 ]

10 голосов
/ 03 марта 2011

Попробуйте

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
4 голосов
/ 03 марта 2011

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

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

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)
3 голосов
/ 03 марта 2011

Нужная вам терминология - «карта» или «словарь»: это приведет вас к нужной странице в документе Python .

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

>>> a = {123:'dave', 345:'mike'}
>>> a[123]
'dave'
0 голосов
/ 03 марта 2011

Отсутствие подчеркивания делает 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))

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...