how to select an object from a list of objects by

2019-03-26 19:09发布

Apologies if this question has already been asked but I do not think I know the correct terminology to search for an appropriate solution through google.

I would like to select an object from a list of objects by the value of it's attribute, for example:

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

in my case the number will always be unique

Thanks for the help

标签: python oop
4条回答
混吃等死
2楼-- · 2019-03-26 19:17

Try

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

or

for person in a.pList:
    if person.num == 123:
        break
else:
    print "Not found."
dave = person
查看更多
我想做一个坏孩纸
3楼-- · 2019-03-26 19:19

The missing underscore makes plist a public property. I don't think that's what you want, since it does not encapsulate the functionality and you could call a.plist.append instead of 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))

If the numbers are unique, you may also consider using a dictionary that maps from number to name or person instead of a list. But that's up to your implementation.

查看更多
Root(大扎)
4楼-- · 2019-03-26 19:32

The terminology you need is 'map' or 'dictionnary' : this will lead you to the right page in the python doc.

Extremely basic example:

>>> a = {123:'dave', 345:'mike'}
>>> a[123]
'dave'
查看更多
淡お忘
5楼-- · 2019-03-26 19:37

If those nom's are unique keys, and all you are ever going to do is access your persons using this unique key you should indeed rather use a dictionary.

However if you want to add more attributes over time and if you like to be able to retrieve one or more person by any of those attributes, you might want to go with a more complex solution:

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

So let's assume we got one Mike and two Dave's

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

Now you can find persons by number:

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

Or by name:

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

Or both:

>>> a.findPerson(nom='dave', num=123)
Person('dave', 123)
查看更多
登录 后发表回答