Python列表来存储类实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3484019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:18:17  来源:igfitidea点击:

Python list to store class instance?

pythonlist

提问by ladyfafa

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,

给定一个 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

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 namesis an instance of Studentso that I can use the attributs of this element despite python is weak type? I hope I made myself clear ;)

我的问题是:如何创建一个可以(如果可以通过任何语句完成)存储 的实例的列表Student?或者更确切地说,当我编写 时,我names = []如何声明中的每个元素names都是一个实例,Student以便我可以使用该元素的属性,尽管 python 是弱类型?我希望我说清楚了 ;)

Can I write like:

我可以这样写:

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

I guess not...

我猜不是...

采纳答案by Katriel

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 namesis misleading, since it is a list of Studentinstances.

请注意,调用列表names具有误导性,因为它是一个Student实例列表。

You can't define the list to be a list of Student instances; that's not how Python works.

您不能将列表定义为 Student 实例的列表;这不是 Python 的工作方式。

Are you asking how to create the list that you've called names?

您是在问如何创建您调用的列表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 forloop.

如果您需要对每一行进行大量处理,那么您可以将处理移动到单独的函数中或使用for循环。

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:

响应您的编辑,我认为您正在尝试在 Python 中声明变量的类型。你写了:

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:

该行的目的是什么student = Student()- 您是否试图声明变量的类型student?不要那样做。以下将执行您的意图:

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

Notice several things:

注意几点:

  1. 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 forloop.
  2. You don't need to make any claims about what studentis -- it could be a string, a boolean, a list, a Student, whatever. This is dynamic typing. Likewise, studentsdoesn't have to be a list; you can iterate over any iterable.
  3. When you write student.gender, Python will get the genderattribute of student, or raise an exception if it doesn't have one.
  1. 我们不需要迭代range(n)然后在 中查找每个实例names;迭代容器的每个元素是for循环的目的。
  2. 你不需要对student是什么做出任何声明——它可以是一个字符串、一个布尔值、一个列表、一个Student,等等。这是动态类型。同样,students不必是列表;你可以迭代任何可迭代的
  3. 当您编写 时student.gender,Python 将获得 的gender属性student,如果没有,则引发异常。

回答by sepp2k

First of all python is notweakly typed. It is however dynamically typed so you can't specify an element type for your list.

首先,python不是弱类型的。但是,它是动态类型的,因此您无法为列表指定元素类型。

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:

然而,使用列表理解来编写它更像是 Pythonic:

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

回答by Jake Levi

I'm fairly new to OOP, but does this not do what you want quite nicely? name_listis a class variable, and every time you create a new Studentobject, 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:

我对 OOP 还很陌生,但这不是很好地满足您的要求吗?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()

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