TypeError: нехэшируемый тип: «Узел»

У меня есть этот код, который находит кратчайший и самый быстрый путь между источником и пунктом назначения.

class Node(object):
    def __init__(self, ID, name, power, generation):
        """
        Creates Node Object

        Requires: (id = int), (name = string), (power = int), (generation = int)
        """
        self.id = ID
        self.name = name
        self.power = power
        self.generation = generation

    def getId(self):
        """
        Gets id atribute.
        """
        return self.id

    def getName(self):
        """
        Get name atribute.
        """
        return self.name

    def getPower(self):
        """
        Get power atribute.
        """
        return self.power

    def getGeneration(self):
        """
        Get generation atribute.
        """
        return self.generation

    def allInfo(self):
        '''
        Gives a representation of each node atribiutes
        '''
        return "ID: " + str(self.id) + " | NAME: " + self.name + " | POWER: " + str(self.power) + " | GENERATION: " + str(self.generation)

    def __str__(self):
        return self.name

    def __eq__(self, other):
        '''
        Sets node if equal to other id if is an instance
        '''
        if isinstance(other, Node):
            return self.id == other.id
        return False```

класс Диграф (объект):

def __init__(self):
    """
    Nodes is a list of the nodes in the graph.

    Edges is a dict mapping each node to a list of its children.
    """

    self.nodes = []
    self.edges = {}

def addNode(self, node):
    """
    Adds the nodes.
    """
    if node in self.nodes:
        raise ValueError('Duplicate node')
    else:
        self.nodes.append(node)
        self.edges[node] = []

деф основной (аргументы): ''' Основная функция, которая получает аргументы в виде файлов, заданных в оболочке, для запуска программы. Требует: args является старым для нескольких файлов, заданных для чтения Гарантирует: Создает выходной файл со временными соединениями станций '''

stations = []
conns = []

file_in = open(args[1], "r")
for line in file_in:
    if (line[0] != "#"):
        station_info = line.split(", ")
        stations.append(Node(int(station_info[0]),
                             station_info[1],
                             int(station_info[2]),
                             int(station_info[3])))
        conns.append(line.split("(")[1].split(", "))

g = Digraph()

for station in stations:
    g.addNode(station)

aux = 0

for station in stations:
    for s in conns[aux]:
        # por \r\n em mac
        pos = (int(s.replace("\n", ""))) - 1
        g.addEdge(Edge(station, stations[int(pos)]))
    aux += 1
file_in.close()

file_in = open(args[2], "r")
maxTest = len(file_in.readlines())
file_in.close()

file_in = open(args[2], "r")
file_out = open(args[3], "w")

count = 0
for line in file_in:
    line = line.replace("\n", "")
    stationNames = line.split(" ")
    stop = False
    stationA = findStation(stations, stationNames[0])

    if stationA == None:
        file_out.write(stationNames[0] + " out of the network\n")
        stop = True

    stationB = findStation(stations, stationNames[1])
    if stationB == None:
        file_out.write(stationNames[1] + " out of the network\n")
        stop = True

    if stationA == stationB:
        file_out.write("Trying to connect same station (" + stationA.getName() + ", " + stationB.getName() + ")\n")
        stop = True

    if not stop:
        file_out.write(str(search(g, stationA, stationB)) + "\n")

    count += 1
    percentage = round(count * 100 / maxTest, 1)
    sys.stdout.write("\r     Progress: " + str(percentage) + "%     |     ")
    sys.stdout.write("Tested: " + str(count) + " of " + str(maxTest) + " connections!")
    sys.stdout.flush()

sys.stdout.write("\n")

file_in.close()
file_out.close()

but i'm getting this error

    C:\Users\André Ramos\Desktop\Project\Project\relayStationsGroup12>python 
    relayStations.py inputFile1.txt inputFile2.txt out.txt

    ##########################  Relay Stations  ############################

    RelayStations is running...

    Traceback (most recent call last):
      File "relayStations.py", line 339, in <module>
       main(sys.argv)
      File "relayStations.py", line 270, in main
       g.addNode(station)
      File "relayStations.py", line 113, in addNode
       self.edges[node] = ()
    TypeError: unhashable type: 'Node'

Ошибка, кажется, добавляется в код, который вы здесь не показали, в relayStations.py строке 113. Я боюсь, что ошибка явная и что вы пытаетесь использовать изменяемый тип в качестве ключа в словаре. Вы должны показать класс Node, если вам нужна дополнительная помощь.

Serge Ballesta 27.05.2019 17:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
1 262
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваши узлы являются экземплярами пользовательского класса Node:

Node(int(station_info[0]),
     station_info[1],
     int(station_info[2]),
     int(station_info[3]))

Но Python словари требует, чтобы их ключи были хешируемый:

An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().

Поэтому, если вы хотите использовать свои узлы в качестве ключей словаря, вы должны реализовать для них магические методы __hash__ и __eq__.

Но у меня есть метод экв.

André Ramos 27.05.2019 18:53

Вам нужен не только __eq__ метод, но и __hash__.

vurmux 27.05.2019 19:02

Другие вопросы по теме