Подтвердить что ты не робот

Список Python для хранения экземпляра класса?

Имеется класс python class Student(): и список names = []; затем я хочу создать несколько экземпляров Student() и добавить их в список names,

names = [] # For storing the student instances
class Student():
    def __init__(self, score, gender):
        self.score = score
        self.gender = gender

А теперь я хочу проверить оценки всех студентов мужского пола, могу ли я сделать это так?

scores = []
for i in names:
    if i.gender ==  "Male":
        scores.append(i.score)

Мой вопрос: как создать список, который может (если это можно сделать с помощью любого оператора) хранить экземпляр Student? Или, скорее, когда я пишу names = [], как я могу утверждать, что каждый элемент в names является экземпляром Student, чтобы я мог использовать атрибуты этого элемента, несмотря на то, что python является слабым типом? Надеюсь, я ясно дал понять;)

Могу ли я написать как

    for i in range(len(names)):
        student = Student()
        student = names[i]
        if student.gender == "Male":
            # Whatever

Я думаю, нет...

4b9b3361

Ответ 1

Вы пробовали свой код выше? Это должно работать нормально. Вы можете сжать это в:

scores = [ student.name for student in names if student.gender == "Male" ]

Обратите внимание, что вызов списка names вводит в заблуждение, поскольку это список экземпляров Student.

Вы не можете определить список как список экземпляров Student; это не так, как работает Python.

Вы спрашиваете, как создать список, который вы назвали names?

names = [ ]
for ( score, gender ) in <some-data-source>:
    names.append( Student( score, gender ) )

что, конечно, эквивалентно

names = [ Student( score, gender ) for score, gender in <some-data-source> ]

и, в свою очередь,

names = [ Student( *row ) for row in <some-data-source> ]

Если вам необходимо выполнить большую обработку для каждой строки, вы можете переместить обработку в отдельную функцию или использовать цикл for.

def process_row( row ):
    ...
    return score, gender

names = [ Student( *process_row( row ) ) for row in <some-data-source> ]

Отвечая на ваши изменения, я думаю, что вы пытаетесь объявить типы переменных в Python. Вы написали:

for i in range(len(names)):
    student = Student()
    student = names[i]
    if student.gender == "Male":
        # Whatever

Какова цель строки student = Student() - вы пытаетесь объявить тип переменной student? Не делай этого. Следующее сделает то, что вы хотели:

for student in students:
   if student.gender == "Male":
       # Whatever

Обратите внимание на несколько вещей:

  1. Нам не нужно перебирать range(n), а затем искать каждый экземпляр в names; перебор каждого элемента контейнера является целью цикла for.
  2. Вам не нужно делать никаких заявлений о том, что такое student - это может быть строка, логическое значение, список, Student, что угодно. Это динамическая типизация. Аналогично, students не обязательно должен быть списком; Вы можете перебрать любую итерацию.
  3. Когда вы пишете student.gender, Python получит атрибут gender для student или вызовет исключение, если у него его нет.

Ответ 2

Прежде всего, Python не является слабо типизированным. Однако он динамически типизирован, поэтому вы не можете указать тип элемента для своего списка.

Однако это не мешает вам получить доступ к атрибутам объекта. Это работает просто отлично:

names = [Student(1,"Male"), Student(2,"Female")]
scores = []
for i in names:
    if i.gender ==  "Male":
        scores.append(i.score)

Тем не менее, более питонно писать это, используя понимание списка:

names = [Student(1,"Male"), Student(2,"Female")]
scores = [i.score for i in names if i.gender == "Male"]

Ответ 3

Я новичок в ООП, но разве это не делает то, что вы хотите, довольно приятно? name_list является переменной класса, и каждый раз, когда вы создаете новый объект Student, он добавляется в Student.name_list. Например, у вас был метод cheat(self), который вы хотели применить к третьему ученику, вы можете запустить Student.name_list[2].cheat(). Код:

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

Выход:

[]
['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']