Python 比较列表中节点的更好方法

Python 比较列表中节点的更好方法,python,list,nodes,Python,List,Nodes,Noob,尝试将“unique”节点添加到列表中,即使用我的简单代码,我只想要2个唯一节点,而不是任何重复的条目。我发现了一个糟糕的解决方法,我创建了一个临时列表,将值(作为列表项,而不是节点)添加到临时列表中(如果唯一),然后将临时列表中的所有项目添加到我的节点列表中(此时将它们转换为节点),但我相信有更好更干净的方法来实现这一点 class Node(): # current actor, source, movie def __init__(self, state, par

Noob,尝试将“unique”节点添加到列表中,即使用我的简单代码,我只想要2个唯一节点,而不是任何重复的条目。我发现了一个糟糕的解决方法,我创建了一个临时列表,将值(作为列表项,而不是节点)添加到临时列表中(如果唯一),然后将临时列表中的所有项目添加到我的节点列表中(此时将它们转换为节点),但我相信有更好更干净的方法来实现这一点

class Node():
    # current actor, source, movie
    def __init__(self, state, parent, action):
        self.state = state
        self.parent = parent
        self.action = action

x = Node(5,4,3)
y = Node(5,4,2)
z = Node(5,4,3)

listz = []

if x not in listz:
    listz.append(x)

if y not in listz:
    listz.append(y)

if z not in listz:
    listz.append(z)

for item in listz:
    print(item.state, item.parent, item.action)

Current Outputs (incorrect):
5 4 3
5 4 2 
5 4 3

Should Output (correct):
5 4 3
5 4 2 

我能遵循和实现的简单解决方案比我不能遵循和实现的聪明解决方案更受欢迎。

您可以在
节点
类中声明一个eq()方法,以您想要的方式轻松比较每个节点

这样做的目的是,每当您插入一个节点并调用
Not in
方法时,它都会调用此
\uuuuuu eq\uuuu
方法,而不是比较节点的默认方式,因此能够检测类似的节点。原始代码的情况是,
不在
中只是比较所有节点的内存位置(这些节点总是不同的)

比如说,

class Node():
    # current actor, source, movie
    def __init__(self, state, parent, action):
        self.state = state
        self.parent = parent
        self.action = action
    def __eq__(self, b):
        return (self.state == b.state) and (self.parent == b.parent) and (self.action == b.action)

x = Node(5,4,3)
y = Node(5,4,2)
z = Node(5,4,3)

listz = []

if x not in listz:
    listz.append(x)

if y not in listz:
    listz.append(y)

if z not in listz:
    listz.append(z)

for item in listz:
    print(item.state, item.parent, item.action)


您所描述的是一个有序集,Python本机不支持它,但您可以使用dict的键来模拟它,它保证自Python 3.7以来保持插入顺序(或者您可以使用
collections.OrderedDict
,用于早期版本)

但是,要使两个具有相同属性值的
节点
对象被识别为与dict的键相同,则应使用相关属性元组中的哈希定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>和
方法:

class Node():
    def __init__(self, state, parent, action):
        self.state = state
        self.parent = parent
        self.action = action
    def __hash__(self):
        return hash((self.state, self.parent, self.action))
        # you can also use the following instead if don't want to hard-code attributes:
        # return hash(tuple(vars(self).values()))
    def __eq__(self, other):
        return hash(self) == hash(other)
以便:

x = Node(5,4,3)
y = Node(5,4,2)
z = Node(5,4,3)

listz = {}
for item in x, y, z:
    listz[item] = None

for item in listz:
    print(item.state, item.parent, item.action)
产出:

5 4 3
5 4 2

如果我需要尝试其他方法,我的代码仍然输出相同的结果:
\uuuu eq\uuu()
方法必须在Node类中,因为它提供对Node对象的操作。我已经对链接上的代码做了相关的更改,现在请注意,列表中的每个成员查找都需要O(n)的时间复杂度,因此如果效率是一个问题,则应该考虑基于哈希的实现,这将允许成员身份查看在一定的时间内完成。