Python list to store class instance? - python

Given a python class class Student(): and a list names = []; then I want to create several instances of Student() and add them into the list names,
names = [] # For storing the student instances
class Student():
def __init__(self, score, gender):
self.score = score
self.gender = gender
And now I want to check out the scores of all the male students, can I do it like this?
scores = []
for i in names:
if i.gender == "Male":
scores.append(i.score)
My question is: How to create a list that can (if could be done by any statement) store the instance of Student? Or rather, when I write names = [], how could I state every element in names is an instance of Student so that I can use the attributs of this element despite python is weak type? I hope I made myself clear ;)
Can I write like:
for i in range(len(names)):
student = Student()
student = names[i]
if student.gender == "Male":
# Whatever
I guess not...

Did you try your code above? It should work fine. You can condense it into:
scores = [ student.name for student in names if student.gender == "Male" ]
Note that calling the list names is misleading, since it is a list of Student instances.
You can't define the list to be a list of Student instances; that's not how Python works.
Are you asking how to create the list that you've called names?
names = [ ]
for ( score, gender ) in <some-data-source>:
names.append( Student( score, gender ) )
which is of course equivalent to
names = [ Student( score, gender ) for score, gender in <some-data-source> ]
and in turn to
names = [ Student( *row ) for row in <some-data-source> ]
If you need to do a lot of processing for each row then you can either move the processing into a separate function or use a for loop.
def process_row( row ):
...
return score, gender
names = [ Student( *process_row( row ) ) for row in <some-data-source> ]
Responding to your edit, I think you are trying to declare the types of variables in Python. You wrote:
for i in range(len(names)):
student = Student()
student = names[i]
if student.gender == "Male":
# Whatever
What is the purpose of the line student = Student() -- are you trying to declare the type of the variable student? Don't do that. The following will do what you intended:
for student in students:
if student.gender == "Male":
# Whatever
Notice several things:
We don't need to iterate over range(n) and then look up each instance in names; iterating over every element of a container is the purpose of a for loop.
You don't need to make any claims about what student is -- it could be a string, a boolean, a list, a Student, whatever. This is dynamic typing. Likewise, students doesn't have to be a list; you can iterate over any iterable.
When you write student.gender, Python will get the gender attribute of student, or raise an exception if it doesn't have one.

First of all python is not weakly typed. It is however dynamically typed so you can't specify an element type for your list.
However this does not prevent you from accessing an object's attributes. This works just fine:
names = [Student(1,"Male"), Student(2,"Female")]
scores = []
for i in names:
if i.gender == "Male":
scores.append(i.score)
It is however more pythonic to write this using a list comprehension:
names = [Student(1,"Male"), Student(2,"Female")]
scores = [i.score for i in names if i.gender == "Male"]

I'm fairly new to OOP, but does this not do what you want quite nicely? name_list is a class variable, and every time you create a new Student object, it gets added to Student.name_list. Say for example you had a method cheat(self) which you wanted to perform on the third student, you could run Student.name_list[2].cheat(). Code:
class Student():
name_list = []
def __init__(self, score, gender):
Student.name_list.append(self)
self.score = score
self.gender = gender
#this is just for output formatting
def __str__(self):
return "Score: {} || Gender: {}".format(self.score, self.gender)
#again for output formatting
def update(): print([str(student) for student in Student.name_list])
update()
Student(42, "female")
update()
Student(23, "male")
update()
Student(63, "male")
Student(763, "female")
Student("over 9000", "neutral")
update()
Output:
[]
['Score: 42 || Gender: female']
['Score: 42 || Gender: female', 'Score: 23 || Gender: male']
['Score: 42 || Gender: female', 'Score: 23 || Gender: male', 'Score: 63 || Gender: male', 'Score: 763 || Gender: female', 'Score: over 9000 || Gender: neutral']

Related

How to use For loop to print all items in python class

I have created a new class:
testing.py:
class student:
def __init__(self, name, major, gpa):
self.nm = name
self.mj = major
self.gp = gpa
then, I move to my working file testing.py:
from testing import student
student1=student("Marcos","Physics",3.99)
student2=student("Phillyp","Biology",2.99)
student3=student("Naim", "Architecture", 3.42)
for k in range(1,4):
print(student(k).gp) <------- how do I merge this string with int!?!?
my final aim is to print out ALL the gpa of all students, so I know I need to do
print(student1.gp)
print(student2.gp)
print(student3.gp)
So how can I concatenate the k into the variable name to produce student1.gp, student2.gp etc?
Thank you all so much!
instead of this for k in range(1,4): you want to iterate over a list of all of your students:
students = [student1, student2, student3]
for student in students:
print(student.gp)
EDIT
If you want to be able to reference the students by name, store them in a dict:
students = {'student1': student("Marcos","Physics",3.99),
'student2': student("Phillyp","Biology",2.99),
'student3': student("Naim", "Architecture", 3.42)}
for i in range(1, 4):
print(students[f'student{i}'].gp)
# if less than python 3.6
# print(students['student{}'.format(i)].gp)
What you should be doing is putting all the objects in list. E.g.
from testing import student
student1 = student("Marcos","Physics",3.99)
student2 = student("Phillyp","Biology",2.99)
student3 = student("Naim", "Architecture", 3.42)
students = [student1, student2, student3]
for student in students:
print(student.gp)

How to create and set variables as classes from a list of tuples?

I am trying to figure out how to create variables from a list of tuple and assign them to a class.
I have data organized like this
Name Age Status
John 30 Employed
That I have created a list of tuple like this
employeelist = [(John, 30, Employed), (Steve, 25, Part-Time)]
And a class set up like this
class Employee():
ecount = 0
elist = []
def __init__(self, name, age, emp_status):
self.name = name
self.age = age
self.emp_status = emp_status
self.lookup = {}
Employee.ecount = Employee.ecount+1
Employee.elist.append(self.name)
Using this code I am able to turn the tuple into an instance of the class
for i in range(0, len(employeelist),1):
sublist = [str(n) for n in employeelist[i]]
Employee(sublist[0], sublist[1], sublist[2])
But I am not able to access them. Is there a way to think about setting up the for loop to create a variable from sublist[0] and then create a class out of it (e.g. sublist[0] = Employee(sublist[0], sublist[1], sublist[2]))?
You just need
employees = [Employee(*v) for v in employee_list]
Note that employees and Employee.elist are essentially the same once
each Employee object has been created.

Accessing method variables of one class in another python class

I have started learning Object Oriented concepts in python. I have got this sample code below:
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
class School(object):
students = []
def __init__(self, name):
self.name = name
def add_student(self, student):
self.students.append(student)
def show_students(self):
print("{0} Student Roster".format(self.name))
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
my_school = School("Quora University")
first_student = Student("Rongan Li", 20)
second_student = Student("Jason Kane", 20)
my_school.add_student(first_student)
my_school.add_student(second_student)
my_school.show_students()
Question:
In the def show_students method of School class how they are accessing the construct variables of class student without instance of that class?
first_student = Student("Rongan Li", 20)
second_student = Student("Jason Kane", 20)
These lines create object of student class ,first_student which has name 'Rongan Li' and age '20'.
second_student which has name 'Jason Kane' and age '20'
Now, you add these 2 objects to the list.
my_school.add_student(first_student)
my_school.add_student(second_student)
Now, when you iterate in the list
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
's' goes to first element of list, and since it is an object of class Student , 's' becomes object of student class. Now, since 's' is first element in the list and on first place you added 'Rongal Li' and 20 . So, s has 2 properties name and age. When you do s.name , it prints 'Rongal Li' and s.age prints 20
Then it goes to next element and same process is repeated.
in the method show_students there's a for loop :
for s in self.students:
print("{0}: {1}".format(s.name, s.age))
it loops over the list of students added by method add so inside the loop the variable "s" represent an instance of student class so s.name is a legit way of accessing an instance variable by using an instance of the class
The students are added to School.students list via the add_student method.
my_school.add_student(first_student)
my_school.add_student(second_student)
These two lines add two references to the School.students list in my_school. So now the list has two references pointing at first_student and second_student.
You can think of the list in my_school at this point as
students = [Pointer to first_student, Pointer to second_student]
When you call my_school.show_students(), my_school.students list (the list above) is accessed and through the references to first_student and second_student in the list, you access the original first_student object and second_student object and can then retrieve their properties.

Using classes in Python

If I have 5 pieces of relevant data, I think it's fair to use a class in order to sort data effectively. However, I need to add these vars to a list.
If I have class "student(name, grade, attendance)", and I'm appending these values to a list, what would that look like?
# student class, inits with name and student id
class Student:
def __init__(self,name,grade, attendance):
self.name = name
self.grade = grade
self.attendance = attendance
def __str__(self):
return self.name
# list of students
students = []
# creates two students
s1 = Student('terry', 99, 99)
s2 = Student('jack', 42, 1)
# add students in the list
students.append(s1)
students.append(s2)
print students

Searching a list to see if there is a match python

Basically this is within a class which appends objects of another class to list self. There are 200 objects in list self. So basically if I call self[1] I will get ['John',['Alex', 'Rob']. Basically 'john' refers to self.firstname and the other names refer to there group members. For example the below will print the firstnames and groupmembers of each object for all 200 objects
for line in self:
print line.firstname
for line in self:
print line.groupmembers
Now I have to create something that goes through all the names and checks the names. So basically if John has Alex and Rob as members then there has to be another object with a first name Alex and another object with a firstname Rob. So say there is no object with firstname Alex I want to print 'mismatch'. This is what I have so far but its not doing what its intended to do.
def name(self):
firstnames = []
for item in self:
firstnames.append(item.firstname)
for item1 in self:
for i in item1.groupmembers:
if i not in hello:
print 'mismatch'
Okay so first off, line and self are bad variable names.
self should only be used within a class to be used as a way to call or use its own variables.
Secondly, you say each value in this self list contains values like ['John',['Alex', 'Rob'], but then you go on to use it like a class object... and frankly that don't do make none sense.
So to remedy this, I'm going to assume its done with class objects. I would also rename self to something like school, and instead of calling an element of self; line, which yields no information to the reader.. call it a student!
I'm going to assume your class would start looking like this:
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
Then if you have a list of people you can loop through them like so..
>>>school = [Student("foo", ["bar", "that guy"]),
Student("bar", ["foo", "that guy"])]
>>>for student in school:
print student.firstname
print student.groupmembers
foo
["bar", "that guy"]
bar
["foo", "that guy"]
Then to check it a students group members are in school you can add a function to the Student class
class Student:
# having an empty default value makes it easy to see what types variables should be!
firstname = ""
groupmembers = []
def __init__(self,firstname,groupmembers ):
self.firstname = firstname
self.groupmembers = groupmembers
def group_present(self, school):
# This is how you would get all the names of kids in school without list comprehension
attendance = []
for student in school:
attendance.append(student.firstname)
# this is with list comprehension
attendance = [ student.firstname for student in school]
#compare group members with attendance
#note that I write student_name, not student
## helps point out that it is a string not a class
for student_name in self.groupmembers:
if not student_name in attendance:
print "Group member '{}' is missing :o!! GASP!".format(student_name)
In idle:
>>> school[0].group_present(school)
Group member 'that guy' is missing :o!! GASP!
Hope that helps!
I am not sure if i understand exactly but maybe you can use contains
self[1].__contains__('Alex')
this should return true in case of existence or false otherwise.

Categories

Resources