Seltsames Verhalten in der Schleife

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
gottlieb
User
Beiträge: 21
Registriert: Freitag 15. März 2013, 14:22

Hallo,
ich hab mal wieder ein Frage an die Erfahrenen von euch.
Hab einen Code geschrieben um zwei Listen miteinander zu vegleichen. Folgender Schnippsel unten soll einfach aus einer der beiden Listen alle Zeilen mit dem Inhalt des Vektors "messageIDs_to_update" rauslöschen. Die Listen liegen als Matrizen vor, der Wert mit dem Verglichen wird ist jeweils der zweite Eintrag einer Zeile.

Problem: Bis zum 7ten Eintrag des Vektors "messageIDs_to_update" funktioniert alles einwandfrei. Danach werden die Werte nicht mehr aus der Liste gelöscht. Die Variablen "end" und "lenght" kann ich aber ausgebenlassen, die Werte werden also in der Liste gefunden, nur eben nicht gelöscht.

Code: Alles auswählen

def delete_interval(lenght, end, data):
        lower = end - lenght
        upper = end
        #print lower
        #print upper
        del data[lower:upper]
        #print len(data)
        return data
print len(new_active_lines)                                     #deletes new messages from active lines, to compare old with new file

for message in messageIDs_to_update:
        end = 0
        lenght = 0
        for line in new_active_lines:
                if message in line[1]:
                        lenght=lenght+1
                end = end + 1
        print message
        print lenght
        print end
        new_active_lines = delete_interval(lenght, end, new_active_lines)
print len(new_active_lines)         
Zuletzt geändert von Anonymous am Montag 15. April 2013, 15:39, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@gottlieb: Also mir kommt der Algorithmus an sich sehr seltsam vor. Du verschiebst `end` und erhöhst `length` aber die betroffenen Elemente müssen am Ende nichts mit der ``if``-Bedingung zu tun haben. Das wäre nur der Fall wenn alle positiven Vergleiche nacheinander in `new_active_lines` vorkommen. Ist das sichergestellt? Oder ist es tatsächlich egal ob bei den gelöschten Elementen die Bedingung zutrifft oder nicht?

Kannst Du beschreiben was Du *eigentlich* machen willst? Also nicht als Lösung formuliert sondern die Problemstellung.
gottlieb
User
Beiträge: 21
Registriert: Freitag 15. März 2013, 14:22

Hi,
ja es ist tatsächlich so, dass die Einträge, wenn dann direkt hintereinander kommen. Daher steht das end da schon ganz gut glaub ich.
Also mein Zeil ist es:
Ich habe einen Vektor von Namen. Und eine Liste mit vielen Tausend Zeilen. Die Einträge in der Liste sind geordnet. Die Zeilen (CAN-Botschaften) mit gleichem Namen folgen also aufeinander. Ich will nichts weiter machen als die Zeilen aus der Liste löschen, deren Name im Vektor steht.
Danke für die Hilfe!
Gruß
BlackJack

@gottlieb: Dann geht man aber doch nicht so umständlich vor. Man geht *einmal* die Liste durch und übernimmt in eine neue Liste nur die Elemente deren Name nicht in der Namensliste vorkommt die gelöscht werden sollen. Wobei die Namen dann am besten in einem `set()` gespeichert werden, damit der Test performant ist.

Edit: Was ist ein Vektor? Wenn das eine Liste ist, dann solltest Du keine neue, ungewöhnliche Nomenklatur einführen.

Edit2: Von Deiner Beschreibung her:

Code: Alles auswählen

message_ids = set(messageIDs_to_update)
new_active_lines = [line for line in new_active_lines if line[1] in message_ids]
Dein Code suggeriert aber etwas anderes weil dort ``message in line[1]`` getestet wird. Hast Du die *ID* nicht in einer Form in der man sie auch tatsächlich direkt vergleichen kann? Was ist `line`? Für mich sieht das eher nach `row` aus. Also Tabellenzeile und nicht Textzeile.
gottlieb
User
Beiträge: 21
Registriert: Freitag 15. März 2013, 14:22

Moin BlackJack,
Edit: Was ist ein Vektor? Wenn das eine Liste ist, dann solltest Du keine neue, ungewöhnliche Nomenklatur einführen.
Ein Vektor ist für mich eine 1-Dimensionale Liste, also einfach eine Folge von Werten (hier strings). Vielleicht, da hast du recht, von der Nomenklatur nicht optimal. Aus Gewohnheit spreche ich immer von Vektoren und Matrizen.
Dein Code suggeriert aber etwas anderes weil dort ``message in line[1]`` getestet wird. Hast Du die *ID* nicht in einer Form in der man sie auch tatsächlich direkt vergleichen kann? Was ist `line`? Für mich sieht das eher nach `row` aus. Also Tabellenzeile und nicht Textzeile.
Line ist tatsächlich row, also eine Zeile einer Tabelle. Da ich im Rest des Skriptes häufig eine doppelte for-Schleife verwende in der zwei Tabellen abgetastet werden, hab ich für den einen Tabellentyp line und für den anderen row reserviert. Entsprechende Zeile, an deren 2ter Stelle die ID steht soll gelöscht werden.
Die Einträge werden alle aus Exceltabellen übernommen. Das "in" habe ich an der Stelle, weil ich sichergehen wollte, dass auch Einträge erfasst werden, in denen zb. ein Leerzeichen am Ende oder am Anfang vorkommt. Wo du es erwähnst fällt mir aber gleich eine andere Lücke auf.
Dann geht man aber doch nicht so umständlich vor. Man geht *einmal* die Liste durch und übernimmt in eine neue Liste nur die Elemente deren Name nicht in der Namensliste vorkommt die gelöscht werden sollen.
Die von dir vorgeschlagene Methode habe ich zuerst probiert und hatte da immer das Problem, dass die gleiche Zeile mehrmals gespeichert wurde. Allerdings habe ich da den set() Befehl nicht benutzt, sondern zwei for-Schleifen. Und dazu in ungünstiger Abfolge wie mir jetzt auffällt. So weit hatte ich irgendwie vorher nicht gedacht :D...
Gruß
gottlieb
User
Beiträge: 21
Registriert: Freitag 15. März 2013, 14:22

Problem gelöst danke!
Antworten