如果我有一个名为Person的类,并且这个类包含每个人的姓名,年龄等,如果我用Person类填充一个列表,我想检查名称是否在列表中而不创建新的只是名字的列表。如果我使用 repr 并返回repr(self.name),我可以打印列表并让它返回列表中每个人的名字列表。如果我然后检查是否" steve"在列表中它返回False。我猜这是因为它正在比较"史蒂夫"每个班级,而不是班级 repr 。有没有办法在不创建新列表的情况下执行此操作?
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr(self.name)
people = [Person('steve', 25), Person('dan', 30),Person('heather', 19)]
print(people)
print('steve' in people)
答案 0 :(得分:1)
使用any()
:
any(p.name == 'steve' for p in people)
#True
......并且失败测试:
any(p.name == 'bob' for p in people)
#False
但是,为了能够使用in
,您需要定义__eq__
,而不是__repr__
:
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, s):
return s == self.name
现在它按预期工作:
'steve' in people
#True
'bob' in people
#False
答案 1 :(得分:1)
最简单的方法可能是手动执行此操作:
steve_in_people = any('steve' == repr(person) for person in people)
您还可以使用布隆过滤器快速确定列表中的'steve'是否,但如果不检查列表,则无法确定。你也可以使用像B-Tree这样的东西来快速执行这个检查(最坏的情况就像O(m),其中m是你正在寻找的字符串的长度)。
如果你不想要花哨的数据结构并且更喜欢pythonic ......那么,使用一个set,它将为你提供非常高性能的in
检查(几乎是恒定时间):< / p>
names = {repr(person) for person in people}
steve_in_people = 'steve' in names
@JoeIddon对修改类以便轻松支持此行为提出了一个很好的观点。我建议进一步改进:
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name
def __eq__(self, s):
return s == self.name
# This will allow you to quickly find this object in a set using its name
def __hash__(self):
return hash(self.name)
现在您可以创建一组Person
个对象并使用名称字符串搜索它:
person_set = set(all_person_objects)
steve_in_people = 'steve' in person_set