我有一个定义如下的课程:
class Members(object):
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
然后我创建了2个包含该类实例的列表:
CourseA = []
CourseB = []
// Extract (multiple) first_name, last_name, age from a file
CourseA.append(Members(first_name, last_name, age)) # called multiple times
// Extract (multiple) first_name, last_name, age from a file
CourseB.append(Members(first_name, last_name, age)) # called multiple times
所以基本上我有两个如下列表:
# CourseA
John, Smith, 12
Jane, Doe, 14
Susan, Patton, 13
# CourseB
Richard, Lane, 12
Susan, Patton, 13
现在,我要比较first_name
和last_name
的{{1}}和CourseA
。如果两者相同,则打印相应的年龄。在这种情况下," Susan Patton"是两个列表中的通用名称,所以我打印" 13"。
最有效的方法是什么?两个列表都很大,我想将CourseB
中的一个名称与CourseA
中的所有名称进行比较,然后将CourseB
中的下一个名称与CourseA
中的所有名称进行比较,但是这似乎是一种非常缓慢的方法。
ETA:所以现在我在课程定义中包含了以下内容。
CourseB
然后,我有以下做比较。顺便说一下,即使我的类定义中没有def __hash__(self):
return hash((self.first_name, self.last_name))
def __eq__(self):
try:
return (self.first_name, self.last_name) == (other.first_name, other.last_name)
except AttributeError:
return False
和__eq__
,下面的比较似乎也能正常工作。
__hash__
我确实得到了CourseA_set = set((x.first_name, x.last_name) for x in CourseA)
CourseB_set = set((y.first_name, y.last_name) for y in CourseB)
for (caller, callee) in CourseA_set.intersection(CourseB_set):
print ("Found: {0}".format((caller, callee)))
和first_name
中的last_name
和CourseA
。但是,如何从CourseB
和CourseA
获取其他相应的属性,例如CourseB
?
我是否必须在age
和CourseA
列表中搜索匹配CourseB
才能获得相应的年龄?这似乎效率低下。
答案 0 :(得分:1)
您正在使用包含其属性的元组替换类实例。您应该将实例保持在列表中,然后将列表转换为集合而不从类中删除属性
CourseA_set = set(CourseA) # no set comprehension
CourseB_set = set(CourseB)
for member in CourseA_set.intersection(CourseB_set):
print ("Found: {f} {l} {a}".format(f=member.first_name,
l=member.last_name,
a=member.age))
您已实施的__hash__
和__eq__
方法将确保在完成交集后,只保留两个集合中匹配first_name
和last_name
的实例。