0

Say you have a list of people.

class Person:
    def __init___(self, name, id):
        self.name = name
        self.id = id

people = []
for x in xrange(0,100)
    #find people and append to people list

Now, I have a list of people objects. How could I most efficiently find, say, a person whose name is "Bob" from the people list?

2
  • 1
    If all of your attributes will be unique, you could construct a dictionary that maps names and ids to specific people. That would be the fastest approach, I think. Commented Sep 8, 2012 at 20:11
  • No, some people can have the same name in my system. Commented Sep 8, 2012 at 20:29

3 Answers 3

4

With just a list and no other indices, you have to use a list comprehension:

matching = [p for p in people if p.name == 'Bob']

but if you have to do that a lot, you may want to create an index:

from collections import defaultdict

nameindex = defaultdict(list)
for person in people:
    nameindex[person.name.lower()] = person

nameindex['bob']  # a list of people named Bob.

This way you only have to loop through all your people once (cost O(N)), after which any name lookup has constant cost (O(1)).

Sign up to request clarification or add additional context in comments.

Comments

1

For this exact scenario, you'll want to use a dictionary:

from collections import defaultdict
people = [...]
name_to_people = defaultdict(list)
for p in people:
    name_to_people[p.name].append(p)

Then whenever you want to find all people whose name is "Bob":

bobs = name_to_people["Bob"]

It will return empty list for no match, a list with one element if there's exactly one person with that name, or a list with multiple elements if there are multiple Bobs.

1 Comment

No need to use a lambda there; use list (the type constructor) instead.
0

One way you could do it is by building a class to hold collections of people objects. One of the best ways to do this may be something like the following code:

class People:
    def __init__(self):
        self.members = {}

    def add_person(self, person):
        self.members[person.name] = person

    def __getitem__(self, name):
        return self.members[name]

class Person:
    def __init__(self, name, id):
        self.name = name
        self.id = id

Now you should be able to fill up the People object like such:

# Add people to a People object
people = People()
people.add_person(Person('Bob', 1))
people.add_person(Person('Surly', 2))

# Get a person by their name
people['Bob']    # Returns instance that is People('Bob', 1)

Also just to let you know, I think your Person class' __init__ method has too many underscores in it. Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.