Charactervergleich im String - bringt zufällige Ergebnisse [gelöst]

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
Pythagoraze
User
Beiträge: 9
Registriert: Dienstag 9. Februar 2021, 10:01

EDIT:
Sorry.
Ich hab es gerade gesehen, ich habe i =+ 1 statt i += 1 gehabt.
So setzte ich ja i immer nur gleich +1, statt zu iterieren.

Moderation: Lassen wir den Thread/Post stehen, oder löschen wir den?
Sorry, war mir nicht eher aufgefallen.

_______________
Moin.

ich wollte eigentlich nur zwei Strings vergleichen. Und wenn die an den Stellen gleich sind, wollte ich ein Zeichen (hier ne Eins) setzen [ich weiß, dafür gäb es builtin-Funktionen, aber später sollen andere Zeichen verglichen werden ... etwas komplexer, das ganze, aber da das mit Zeichen aus dem Alphabet schon nicht richtig hinhaute, wollte ich es wenigstens auf 01 reduzieren]

Code: Alles auswählen

a = "11001"
b = "01010"
c = ""
d = ""
i = 0
for e in a:  # hätte hier auch for i in range(0, len(a)): machen können, oder for i in range(0, 5): , wollte mir aber etwas Tipparbeit sparen
    if a[i] == b[i]:
        c = c + "1"
    else:
        c = c + "0"
    print(a[i],b[i])
    i =+ 1
print(c)
Ausgabe:
>>> %Run VGL.py
1 0
1 1
1 1
1 1
1 1
01111

Aber egal, wie ich die Strings a, b verändere - die Ergebnisse sind irgendwie immer zufällig.
Oder mir nicht nachvollziehbar.
Was stimmt denn damit nicht? Was mach ich falsch?
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
# - mein Python is nur so gut, wie ich - #
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

♪ ♫ Nuuull-Hundert-Neunzich-Draaiii-Drei-Drei .... ♪ ♫ ♪
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Pythagoraze: Wenn Du schon ``for e in a:`` schreibst um Dir Tipparbeit zu sparen, warum sparst Du Dir das mit dem `i` nicht gleich ganz? Noch mehr Tipparbeit gespart und damit hättest Du auch den Fehler gar nicht gehabt: ``for e, f in zip(a, b):``. Kein `i` mehr. Weder vor der Schleife, noch in der Schleife.

Das mit dem ``+=`` bei Zeichenketten ist nicht so gut, das hat potentiell ein böses Laufzeitverhalten, weil Zeichenketten nicht veränderbar sind. Ungetestet:

Code: Alles auswählen

a = "11001"
b = "01010"
c = "".join(str(int(e == f) for e, f in zip(a, b)))
print(c)
Wobei das auch schräg ist die binäre Oder-Verknüpfung auf Zeichenkettenebene zu lösen (ungetestet):

Code: Alles auswählen

a = 0b11001
b = 0b01010
c = a | b
print(f"{c:05b}")
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pythagoraze: Du programmierst mit sehr einfachen Konstrukten, die die Mächtigkeit von Python nicht nutzen, und deshalb aus sehr viel Code mit sehr vielen Möglichkeiten Fehler zu machen, besteht.
Wenn man einen Index in einer for-Schleife braucht, benutzt man enumerate:

Code: Alles auswählen

a = "11001"
b = "01010"
c = ""
for i, e in enumerate(a):
    if a[i] == b[i]:
        c = c + "1"
    else:
        c = c + "0"
    print(a[i],b[i])
Über einen Index zu iterieren ist aber eh falsch, weil man da zu viele Fehler machen kann. Wenn man zwei Sequenzen hat, über die man gemeinsam laufen möchte, benutzt man `zip`:

Code: Alles auswählen

a = "11001"
b = "01010"
c = ""
for zeichen_a, zeichen_b in zip(a, b):
    if zeichen_a == zeichen_b:
        c = c + "1"
    else:
        c = c + "0"
    print(zeichen_a, zeichen_b)
Zeichenketten setzt man aber nicht Stück für Stück zusammen, sondern speichert erst alles in einer Liste und benutzt am Schluß join:

Code: Alles auswählen

a = "11001"
b = "01010"
ergebnis = []
for zeichen_a, zeichen_b in zip(a, b):
    ergebnis.append(
        "1" if zeichen_a == zeichen_b else "0"
    )
    print(zeichen_a, zeichen_b)
c = "".join(ergebnis)
Für solche Art Schleifen gibt es ein spezielles Konstrukt, das sich List-Comprehension nennt:

Code: Alles auswählen

a = "11001"
b = "01010"
ergebnis = [
    "1" if zeichen_a == zeichen_b else "0"
    for zeichen_a, zeichen_b in zip(a, b)
]
c = "".join(ergebnis)
Den Zwischenschritt "Liste" braucht man eigentlich nicht:

Code: Alles auswählen

a = "11001"
b = "01010"
c = "".join(
    "1" if zeichen_a == zeichen_b else "0"
    for zeichen_a, zeichen_b in zip(a, b)
)
Und jetzt kann man noch die spezielle Eigenschaft von Wahrheitswerten nutzen, dass int(True) == 1 und int(False) == 0:

Code: Alles auswählen

a = "11001"
b = "01010"
c = "".join(
    str(int(zeichen_a == zeichen_b))
    for zeichen_a, zeichen_b in zip(a, b)
)
oder wenn man viele Klammern mag:

Code: Alles auswählen

from operator import eq

a = "11001"
b = "01010"
c = "".join(map(str, map(int, map(eq, a, b))))
Benutzeravatar
DeaD_EyE
User
Beiträge: 1205
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Hoffentlich sind die Zeichenketten immer gleich lang. Wenn sie das sein müssen, würde ich bei der Funktion zip() noch strict=True nutzen. Das wirft dann einen ValueError.
ValueError: zip() argument 2 is longer than argument 1
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten