如果<string>不在<somelist> .name中

时间:2015-08-31 09:18:30

标签: python python-3.x scripting

我有一个包含一些字符串的列表。 在添加新字符串之前,我检查该字符串是否已经在列表中,否则,添加它:

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方式是什么?

3 个答案:

答案 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)