Seite 1 von 1

"Int Object is not subscriptable" Fehlermeldung bei Zugriff auf Liste

Verfasst: Mittwoch 16. Juni 2021, 20:25
von kokunamatata
Moin, ich bekomme leider den obigen Fehlercode beim Aufruf meiner Funktion. Ich habe zunächst eine leere Liste, eine Funktion zum hinzufügen von Einträgen und die entsprechenden Einträge definiert. Hierbei handelt es sich um Knoten in einem Koordinatensystem, wobei das erste Tutel die x bzw. y Koordinate angibt. Nun möchte ich in der letzten Funktion die Distanz zwischen zwei Knoten berechnen, wobei eben die Fehlermeldung auftritt. Ich denke es ist irgendwie ein Problem durch die Art des Zugriffes auf die Einträge oder so, aber bin mir nicht sicher und komme leider nicht mehr weiter. Kann jemand helfen? Wäre sehr dankbar

Code: Alles auswählen

nodes = []

def add_node(posn, weight, value, neighbours):
    nodes.append([posn, (weight), (value), neighbours])

add_node((1,1), 1, 3, [2,3])
add_node((0,4), 2, 1, [None])
add_node((4,2), 2, 4, [1,2,4])
add_node((2,2), 3, 3, [2,3,5])
add_node((5,5), 2, 2, [2,4])

def distance_links(node1, node2):
    x2 = int(nodes[node1][1][1])
    x1 = int(nodes[node2][1][1])
    y2 = int(nodes[node1][1][2])
    y1 = int(nodes[node2][1][2])
    result = abs(((((x2 - x1) ** 2) + ((y2 - y1) ** 2)) ** .5))
    return result

print(distance_links(1, 3))

Re: "Int Object is not subscriptable" Fehlermeldung bei Zugriff auf Liste

Verfasst: Mittwoch 16. Juni 2021, 20:53
von Sirius3
Man benutzt keine globalen Variablen. Die Klammern um einzelne Variablen sind überflüssig. Statt einer Liste möchtest Du ein Tuple in der Liste speichern, oder besser noch ein namedtuple. Die Funktion add_node ist aber fast überflüssig, weil sie doch nur aus einem Befehl besteht. Was soll bei posn das n bedeuten?
Python zählt beim Index ab 0. Aber wie schon geschrieben ist es besser, ein namedtuple zu benutzen, statt magischer Indexwerte. Für die Koordinaten bietet sich Tupleunpacking an.
Da es sich bei den Koordinaten schon um ints handelt, ist eine Umwandlung unnötig.
Statt einen Index an distance_links zu übergeben, würde man am besten gleich das Nodeobjekt übergeben.
Warum gehören x1 und y1 zu node2, und x2/y2 zu node1?
Die Formel zur Abstandsberechung hat wieder etwas viele Klammern. Die Wurzelfunktion liefert immer positive Werte, abs ist also überflüssig.

Code: Alles auswählen

from collections import namedtuple

Node = namedtuple("Node", "position, weight, value, neighbours")

def add_node(nodes, position, weight, value, neighbours):
    nodes.append(Node(position, weight, value, neighbours))


def distance_links(node1, node2):
    x1, y1 = node1.position
    x2, y2 = node2.position
    return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** .5

def main():
    nodes = []
    add_node(nodes, (1,1), 1, 3, [2,3])
    add_node(nodes, (0,4), 2, 1, [None])
    add_node(nodes, (4,2), 2, 4, [1,2,4])
    add_node(nodes, (2,2), 3, 3, [2,3,5])
    add_node(nodes, (5,5), 2, 2, [2,4])
    print(distance_links(nodes[0], nodes[2]))

if __name__ == "__main__":
    main()

Re: "Int Object is not subscriptable" Fehlermeldung bei Zugriff auf Liste

Verfasst: Mittwoch 16. Juni 2021, 20:58
von __blackjack__
@kokunamatata: Was soll das `None` in der einen Liste bedeuten? Falls der Knoten keine Nachbarn haben sollte, dann wäre das besser einfach nur eine leere Liste.

Es ist auch ein bisschen fehleranfällig wenn die Nummern in diesen Listen Indexwerte (+1) sein sollten.

Re: "Int Object is not subscriptable" Fehlermeldung bei Zugriff auf Liste

Verfasst: Mittwoch 16. Juni 2021, 21:00
von LukeNukem
kokunamatata hat geschrieben: Mittwoch 16. Juni 2021, 20:25 Moin, ich bekomme leider den obigen Fehlercode beim Aufruf meiner Funktion.
Äh... nein, Du bekommst die Fehlermeldung beim Zugriff auf Deine Daten...
kokunamatata hat geschrieben: Mittwoch 16. Juni 2021, 20:25

Code: Alles auswählen

int(nodes[node1][1][1])
nodes[node1] gibt Dir bereits einen Node zurück, nodes[node1][1] das zweite Element davon -- das ist aber eine Integer, und jetzt versuchst Du mit [1] nochmal das zweite Element Deiner Integer... genau, peng. Mit

Code: Alles auswählen

int(nodes[node1][1])
funktionierts.

NB: anstelle Deiner globalen Variablen "nodes" wäre es möglicherweise eleganter, das mit einer Klasse abzubilden. Ansonsten sieht mir das, was Du da baust, sehr nach einer Datenstruktur aus, die "Graph" genannt wird -- und da ist es nach meiner Erfahrung meistens besser, die Nodes (Vertices) und ihre Verbindungen (Edges) in zwei separaten Eigenschaften einer Klasse zu verwalten... HTH, YMMV.

Re: "Int Object is not subscriptable" Fehlermeldung bei Zugriff auf Liste

Verfasst: Donnerstag 17. Juni 2021, 06:13
von ThomasL
Wenn LukeNukem recht hat kann ich da etwas empfehlen: https://networkx.org/