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

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kokunamatata
User
Beiträge: 1
Registriert: Mittwoch 16. Juni 2021, 20:19

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))
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

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()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

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.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Wenn LukeNukem recht hat kann ich da etwas empfehlen: https://networkx.org/
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten