Inception
Inception

Reputation: 11

Get attribute from object in list of objects created by loop

I create multiple objects of a class Student, by using a loop and saving them in the list object_list.

Now I want to create a function, which gives me back one specific attribute of a certain object from the object list. For example the attribute "name" of the third created object.

Perhaps it is possible to do this with the getattr() function, but the problem is that every created object is called the same ("Student").

Is there a way to index the object description "Student" while creating them in the loop, like Student_1, Student_2, Student_3?

This is my code in which I create the objects:

# Definition of the class Student
class Student(object):
    name = ""
    degree = ""
    grade = ""
    
    def __init__(self, name, degree, grade):
        self.name = name
        self.degree = degree
        self.grade = grade


object_list = []

# Create objects
def create_objects(data):
    x = 0

    # Loop through lists of data
    for list in data[1:]:
        x = x + 1
        # Get values from data to instantiate objects
        object_list.append(Student(get_value(data, x, 0), get_value(data, x, 1), get_value(data, x, 2))

    return object_list

Now I want to create a function I can use like this:

get_attribute(object_list, "Student_3", "name")

How do I call a specific object from the object_list?

Upvotes: 1

Views: 3207

Answers (4)

Tyler Russin
Tyler Russin

Reputation: 106

You could use a dictionary to solve your problem instead of a list.

You simply create a new dictionary key with the x iterated value.

object_dict = {}

# Create objects
def create_objects(data):
    x = 0

    # Loop through lists of data
    for list in data[1:]:
        x = x + 1
       
        # Get values from data to instantiate objects
        object_dict['Student_' + str(x)] = Student(get_value(data, x, 0), get_value(data, x, 1), get_value(data, x, 2))

    return object_dict

Now as far as the get_attribute(object_list, "Student_3", "name") function. It could look something like this.

def get_attribute(object_dict, student, attribute):
  student_num = object_dict[student]
  return student_num.attribute
   

Hope this helps!! Happy coding!

Upvotes: 0

Sebastian Baum
Sebastian Baum

Reputation: 363

first of all I recommend you to use an enumeration. You don't need to iterate with the x manually. Second you can concatenate multiple strings and init your student.

    for idx, list in enumerate(data[1:]):
        #You dont need x anymore


        name = str(get_value(data, x, 0)) + str(idx) #Append the Number of the index
        degree = get_value(data, x, 1)
        grade = get_value(data, x, 2)

        object_list.append(Student(name, degree, grade)

You can implement the Function just like you said with getattr()

    def get_attribute(list, value, attribute):

        for object in list:
            if getattr(object, attribute) == value:
                return object

        #If nothing has the name
        return None

Upvotes: 0

CallMePhil
CallMePhil

Reputation: 1657

def get_attribute(obj_list, index, attribute):
    return getattr(obj_list[index], attribute)

# Gets the name of the 3rd student created
get_attribute(object_list, 3, "name")

Upvotes: 0

Samwise
Samwise

Reputation: 71454

You probably don't want to define your attributes at the class level as well as the instance level:

# Definition of the class Student
class Student(object):
    # no class attributes
    def __init__(self, name, degree, grade):
        # these are all instance attributes
        self.name = name
        self.degree = degree
        self.grade = grade

An easy way to get an object matching certain criteria from a list is to use a filter, which you can do with the filter() function or by just putting an if in a comprehension:

>>> object_list = [Student("Bob", "first", "A"), Student("Biff", "second", "B"), Student("Betty", "third", "C")]
>>> [s for s in object_list if s.name == "Biff"]
[<__main__.Student object at 0x000001855B7D2D60>]
>>> [s for s in object_list if s.name == "Biff"][0].degree
'second'

If you want to use the name of the attribute as a string, you can indeed use getattr:

>>> [s for s in object_list if getattr(s, "name") == "Biff"][0].degree
'second'

If you're doing something like that, though, you probably want to use a regular dict instead of an object:

>>> def student(name, degree, grade):
...     return {"name": name, "degree": degree, "grade": grade}
...
>>> object_list = [student("Bob", "first", "A"), student("Biff", "second", "B"), student("Betty", "third", "C")]
>>> [s for s in object_list if s["name"] == "Biff"]
[{'name': 'Biff', 'degree': 'second', 'grade': 'B'}]

Upvotes: 1

Related Questions