Python 从多个列表创建唯一的对象列表

Python 从多个列表创建唯一的对象列表,python,performance,Python,Performance,我定义了一个具有多个字段的自定义对象 例如,假设我有一个Student对象,它由名称、ID和年龄组成。为了比较两个学生并确定他们是否是同一个学生,我实现了一个\uuuiq\uuuu方法,该方法将返回两个学生的年龄、姓名和ID是否匹配 def __eq__(self, other): return self.name == other.name and self.ID == other.ID and self.age == other.age 定义(自身、其他): 返回self.name==

我定义了一个具有多个字段的自定义对象

例如,假设我有一个Student对象,它由名称、ID和年龄组成。为了比较两个学生并确定他们是否是同一个学生,我实现了一个
\uuuiq\uuuu
方法,该方法将返回两个学生的年龄、姓名和ID是否匹配

def __eq__(self, other): return self.name == other.name and self.ID == other.ID and self.age == other.age 定义(自身、其他): 返回self.name==other.name和self.ID==other.ID和self.age==other.age 请记住,学生只是一个例子,因此学生ID往往是唯一的这一事实没有被考虑

假设我有以下注册列表,其中包含任意数量的学生对象

[S1, S2, S3] [S2, S3] [S3, S5, S4] [S1, S4, S2, S1] [S1、S2、S3] [S2,S3] [S3、S5、S4] [S1,S4,S2,S1] 我想创建一些包含以下元素的数据结构

S1, S2, S3, S4, S5 S1、S2、S3、S4、S5 最简单的方法是初始化一些可以容纳大量内容的数据结构,抓取一个项目,检查它是否存在于结构中,如果不存在,则添加它

new_list = some_new_list for each list of students: for each student in the list: check if the student is in new_list #decide what to do 新列表=一些新列表 对于每个学生名单: 对于列表中的每个学生: 检查学生是否在新名单中 #决定做什么 如果我决定将其作为一个简单的列表来实现,那么随着我的列表的不断增长,我可能会做很多比较,特别是如果我有一个数量惊人的学生和招生列表的话

什么是有效的实施方式?两者都用于比较两个对象,然后使用该比较方法生成一组唯一的对象

编辑:所以我尝试了一个简单的集合实现

>>>a = Student("sample", 1234, 18) >>>b = Student("sample", 1234, 18) >>>students = set() >>>students.add(a) >>>b in students False >>>b == a True >>>a=学生(“样本”,1234,18) >>>b=学生(“样本”,1234,18) >>>学生=集合() >>>学生。加上(a) >>>b.学生 假的 >>>b==a 真的
我做错什么了吗?

我只有一句话要对你说

设置

您将获得唯一的项,并且只在每个iterable上迭代一次<代码>链使一个长的iterable由一系列iterable组成。如果您需要对其进行排序,
sorted(myset)
将为您提供一个排序列表

你的
学生
班级需要实现一个与
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
兼容的

def __hash__(self):
    return (self.name, self.ID, self.age).__hash__()

为什么不使用内置的集合类型?成员资格测试可能比纯Python中的效率更高。@omrib,因此迭代每个学生列表,然后调用newSet.add(student)就可以了?@agf,哦,我原以为只要检查集合中是否存在项就足够了。ie:“测试会员资格”你不必检查他们是否在集合中。只需将它们全部添加,集合将最终保存唯一的条目。这比单独检查一个是否唯一要快。查看我对
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
@agf的编辑,可能。尽管如此,当我实现了hash方法并尝试了两个具有相同名称ID和年龄的不同学生对象(即:同一个学生)时,它们都被添加到集合中。如果学生列表的数量可变(都包含在名为
student\u list
的列表或元组中),则可以使用
set(chain(*student\u list))
@omrib使用
设置(链。从可编辑(学生列表))
,因此不必解包
学生列表。无论是谁写的
itertools.chain
都想到了这一点,不像
map
zip
那样。
def __hash__(self):
    return (self.name, self.ID, self.age).__hash__()