Python Schleife bricht vorzeitig ab, wie lösen?

PIIPAAPO  26.06.2021, 20:48

Kannst du den ganzen Code schicken? Oder zumindest das nötige?


shwullidulli 
Fragesteller
 26.06.2021, 21:02

Leider nicht möglich.

3 Antworten

Von Experte Roderic bestätigt

Dein konkretes Problem kann ich dir leider nicht sagen, dafür müsste ich mehr Code sehen.

Aber hier die Lösung für deine Aufgabenstellung:

label = " A B A C B A C B A C A"
label = label.replace(" ", "") # Leertasten entfernen
intervals = []

for i in range(len(label)):
   if label[i] == "A" and i < len(label)-1:
       intervals.append((label[i], label[i+1]))

print(intervals)

Dein konkretes Problen wird durch diesen Teil hier gelöst:

i < len(label)-1

Das überprüft, ob das A am Ende des Strings steht, oder ob danach noch was kommt.

Woher ich das weiß:Hobby – Programmieren ist mein Hobby & Beruf

shwullidulli 
Fragesteller
 26.06.2021, 22:11

Hat absolut nichts mit meinem Problem bzw. Aufgabe zu tun.

0
MrAmazing2  26.06.2021, 22:15
@shwullidulli

Dann hast du deine Aufgabe in der Frage absolut falsch formuliert.

"Das Programm soll alle A-Intervalle bestimmten" "Ein A-Intervall geht [vom jeweiligen A] bis zum nächsten Buchstaben".

Genau das macht mein Code. Er liefert eine Liste an A-Intervallen.

Und wie du den Fehler vermeidest wenn das "A" am Ende der Datei steht, hab ich dir auch gezeigt:

i < len(label)-1
0
shwullidulli 
Fragesteller
 26.06.2021, 22:19
@MrAmazing2

Eine völlig vereinfachte "Realisierung" auf Kindergartenniveau, welche nichts mit dem realen Problem gemein hat und so unbrauchbar ist. Vielleicht einfach über das konkrete Problem nachdenken und dazu eine konkrete Antwort liefern.

0
MrAmazing2  26.06.2021, 22:27
@shwullidulli

Wenn du in deiner Frage nur eine vereinfachte Version deines Problems lieferst, und uns nichtmal den nötigen Code zur Verfügung stellst, dann erwarte nicht, dass wir eine Antwort zu einem realen Problem herzaubern können - Wir kennen ja dein reales Problem ja nicht.

Mein Code macht genau das, was du in der Frage beschreibst:

In den Dateien stehen z.B. " A B A C B A C B A C" und das Programm soll alle A-Intervalle bestimmen.
Ein A-Intervall geht bis zum nächsten Buchstaben, also das erste A-Intervall geht von A bis B, das zweite A-Intervall geht von A bis C und so weiter.

A B A C B A C B A C

->

(A B), (A, C), (A C), (A C).

Wenn dir das nicht passt, dann beschreibe die Aufgabe genauer, oder zeig uns deinen Code!

0
MrAmazing2  26.06.2021, 22:40
@shwullidulli

Außerdem ein Wunder, dass du dich hier beschwerst, dass dir mein Code zu einfach ist. Deine Python Kenntnisse sind ja selbst noch auf Kindergartenniveau, wenn ich deine letzten Fragen so ansehe - Du kennst ja nichtmal den Unterschied von Tupel und Liste ...

Anstatt dich zu beschweren dass die Antworten unbrauchbar sind, beschreibe deine unbrauchbare Frage genauer. Peace.

2
shwullidulli 
Fragesteller
 27.06.2021, 00:26
@MrAmazing2

Very nice, der Seitenhieb mit Tupel und Liste hat mich auf die Lösung meines Problems gebracht. Ändert aber nichts an deiner falschen Antwort bzw. "Lösung".

1
MrAmazing2  27.06.2021, 00:43
@shwullidulli

Das freut mich haha. Das ist die hauptsache :D

Und wie gesagt, meine Lösung bezieht sich auf die Frage so wie sie jetzt dasteht. Input ist wie von dir gegeben, Output ist wie von dir gewünscht. Das ganze sinnvoll in dein System einzufügen/anzupassen ist deine Aufgabe.

Du kannst nicht einfach sagen meine Lösung wäre falsch, wenn sie die Frage perfekt beantwortet. Dann ist es deine Frage, die falsch (oder zu ungenau) ist. Das sollte dir bewusst werden wenn du dir mal die anderen Kommentare, die Nachfrage und die Bewertungen meiner Antwort anschaust. :P

Aber bei einer Sache war ich mir tatsächlich unsicher bei meiner Lösung - Was wenn zwei mal A dasteht? Daher hier noch eine Alternativlösung, die die beiden As dann in ein (A, A)-Intervall packt, und das zweite A überspringt, anstatt daraus noch ein (A, ..)-Intervall zu machen:

iRange = (i for i in range(len(label)))
for i in iRange:
   if label[i] == "A" and i < len(label)-1:
       intervals.append((label[i], label[i+1])) # Mache Intervall aus "A" und nächsten Buchstaben
       next(iRange, None) # Überspringe in der Schleife den nächsten Buchstaben

Aber wird dir vermutlich auch nix helfen, wenn meine Annahme stimmt, dass du die Aufgabe in der Frage falsch formuliert hast.

Aber ja, freut mich, dass du jetzt die Lösung gefunden hast. ^^

0
shwullidulli 
Fragesteller
 27.06.2021, 01:11
@MrAmazing2

Bin beim Programmieren schnell angepi**t, wenn etwas nicht klaptt, sorry :D

Vielleicht würde deine Lösung nach ein paar Anpassungen auch funktionieren, das Programm ist sehr umfangreich und es sind dutzend verschachtelte for Schleifen die unterschiedliche Dateien vergleichen und umwandeln. Da möchte man echt nicht nochmal alles durchgehen, sondern möglichst direkt nur das Problem im vorhandenen Code lösen :D

Das "AA" Problem ging mir damals auch durch den Kopf, aber dieser Fall kann niemals auftreten, da es sich um Markierungen bestimmter Zeitabläufe handelt die erst mit der nächsten Markierung enden.

Nochmal das Problem: Datei mit Label Reihenfolge A, B, A, C, B stellt kein Problem dar, da das letzte A das Intervall A bis C zugewiesen werden kann.
Datei mit Label Reihenfolge A, B, A, C, A stellt ein Problem dar, da das Letzte A kein Ende findet.
Mit der Tupel/Liste Geschichte kann ich das Array mit den Labels über append erweitern und der Fall, dass ein A am Ende steht ist ausgeschlossen. Das Programm meckert nun auch nicht mehr, allerdings bin ich mir nicht zu 100% sicher, ob es negative Auswirkungen haben könnte..

In dem Teil des Codes werden die Intervalle bestimmt..

for kal, var in enumerate(annotation.aux_note):  
    if var == 'A':     # start A Bereich
        AStart = annotation.sample[kal]
        for j in range(kal, len(label)):

            AStop = annotation.sample[j + 1]
0
MrAmazing2  27.06.2021, 01:30
@shwullidulli

Kein Ding, das kenn ich auch :D

Könnte man anstatt

        for j in range(kal, len(label)):
            AStop = annotation.sample[j + 1]

nicht einfach

            AStop = annotation.sample[len(label)]

machen? Weil momentan überschreibst du AStop einfach immer, bis j bei len(label)-1 angekommen ist. Da könnte man ja gleich len(label) hernehmen. Oder hast du da was rausgestrichen?

Aber zu deinem Problem, das könnte man doch so lösen, or not? :

for kal, var in enumerate(annotation.aux_note):  
    if var == 'A' and kal < len(annotation.aux_note)-1:     # start A Bereich
        AStart = annotation.sample[kal]
        for j in range(kal, len(label)):

            AStop = annotation.sample[j + 1]
0

Sagt dir der Begriff "Reguläre Ausdrücke" (regular expressions oder regex) was?

Von Experte MrAmazing2 bestätigt

Ich bin mir nicht ganz sicher, was genau du erreichen willst, aber könntest du nicht bei einem A in deinem String (ich denke mal es ist ein String) den Index überprüfen und falls dieser gleich der Länge des Strings-1 ist, hast du das Ende erreicht?