如何通过python中的属性从对象列表中选择对象

时间:2011-03-03 11:25:30

标签: python oop

如果已经提出这个问题,我很抱歉,但我认为我不知道通过谷歌搜索合适的解决方案的正确术语。

我想通过它的属性值从对象列表中选择一个对象,例如:

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 个答案:

答案 0 :(得分:10)

尝试

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

答案 1 :(得分:4)

如果这些名词是唯一的密钥,而你所要做的就是使用这个独特的密钥访问你的人,你应该使用字典。

但是,如果您想随着时间的推移添加更多属性,并且您希望能够通过任何这些属性检索一个或多个人,那么您可能希望使用更复杂的解决方案:

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())

所以我们假设我们有一个Mike和两个Dave的

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)

答案 2 :(得分:3)

您需要的术语是“地图”或“字典”:这会引导您the right page in the python doc

非常基本的例子:

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

答案 3 :(得分:0)

缺少的下划线使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))

如果数字是唯一的,您还可以考虑使用从数字到姓名或人而不是列表的字典。但这取决于你的实施。