繁体   English   中英

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

[英]Better way compare nodes in a list

菜鸟,试图将“唯一”节点添加到列表中,即使用我的简单代码,我只想要 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 

我可以遵循和实施的简单解决方案优于我不能遵循和实施的聪明解决方案。

您可以在您的Node class 中声明一个eq () 方法,以便以您想要的方式轻松地将节点与每个节点进行比较。

这样做的作用是每次插入节点并调用Not in方法时,它都会调用此__eq__方法而不是默认的比较节点的方法,因此能够检测到相似的节点。 您的原始代码发生的事情是Not in只是比较所有节点的 memory 位置(它们总是不同的)

例如,

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)

What you're describing is an ordered set, which Python does not natively support, but which you can emulate with keys of a dict, which is guaranteed to maintain insertion order since Python 3.7 (or you can use collections.OrderedDict for prior versions) .

但是,要使具有相同属性值的两个Node对象被识别为与 dict 的键相同,您应该使用 hash 从相关属性的元组中定义__hash____eq__方法:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM