我有一个包含一些字符串的列表。 在添加新字符串之前,我检查该字符串是否已经在列表中,否则,添加它:
myList = []
....
name = "myName"
...
if name not in myList:
myList.append(name)
问题是,需要存储更多信息,而不仅仅是名称。
所以我创建了一个类。
myList = []
myListEntry = someClass()
....
myListEntry.name = "myName"
...
我希望myList现在包含对象而不是字符串。 但是,这样我的 如果myListEntry.name不在myList中: 不再有效。 myList是一个对象列表,因此if语句将始终返回True,从而产生多个相同名称的条目。
我可以想到一个类似C的解决方法,使用oldschool for循环和布尔标志。 但是,解决这个问题的pythonic方式是什么?
答案 0 :(得分:1)
因此,如果您希望列表中的对象仅包含唯一的名称,则必须覆盖您班级的__eq__()
方法。
class A():
def __init__(self, name, value):
self.name = name
self.value = value
def __eq__(self, other):
if isinstance(other, A):
return self.name == other.name
a = A("test", 2)
b = A("test", 3)
c = A("test2", 4)
listA = []
listA.append(a)
if b not in listA:
listA.append(b)
if c not in listA:
listA.append(c)
print listA
这样您就可以使用if _ not in List
答案 1 :(得分:1)
pythonic方法是使用一组来跟踪唯一对象。如果您的集合是专用的(值由特定属性唯一),那么您有两个选项:
如果两个对象被认为是相同的,那么在所有情境中,因为它们的名称相同(并且额外的信息不会改变这一点),所以给出对象object.__hash__()
和{{3}方法,只需将对象添加到集合中。
如果您的对象在此上下文中仅相等,则可以将该集合包装并在自定义object.__eq__()
中提取正确的属性,或者您可以将列表对象和轨道名称包装在一个单独的附加时设置。
后一种方法看起来像这样:
class MyUniqueInfo(object):
def __init__(self):
self._values = []
self._seen = set()
def __getattr__(self, attr):
if hasattr(self._values, attr):
return getattr(self._values, attr)
raise AttributeError(attr)
def append(self, value):
if value.name in self._seen:
return
self._values.append(value)
self._seen.add(value.name)
这样做的另一个好处是它可以保持首先附加项目的顺序。
答案 2 :(得分:0)
假设您的list_of_objects
属性为name
这样的事可能吗?
class Test1:
name = "John"
class Test2:
name = "Johnny"
class Test3:
name = "Jill"
test_object1 = Test1()
test_object2 = Test2()
test_object3 = Test3()
new_list = []
list_of_objects =[test_object2,test_object3]
if test_object1.name not in [object.name for object in list_of_objects]:
new_list.append(test_object1)
print(new_list)