Funktion gibt zusätzlichen Wert aus o.O

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
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

Hi! Ich habe letztens eine Funktion geschrieben, die einen String nach einem anderen kürzeren String durchsucht und die Anzahl der Treffer als
Integer ausgibt. Das tut sie auch, aber sie gibt auch zusätzlich "None" aus. Ich habe dann spaßeshalber den Funktionskörper (nennt man das so? ich glaub schon, berichtigt mich wenn ich falsch liege ._.) schlicht ohne ihn als Funktion zu definieren vom Interpreter abarbeiten lassen, und da tritt das Problem nicht auf, obwohl es, soweit ich das erkennen kann, die gleichen Befehle sind.

Hier die Funktion:


------
def stringsearch(st, wan):

counter = 0
loop = 1
analyze = st
analyze.find(wan)
if st.find(wan) < 0:
loop = 0

while loop == 1:
if analyze.find(wan) >= 0:
counter += 1
cursor = analyze.find(wan) + 1
analyze = analyze[cursor:]
else:
break

print(counter)

string = 'abrakadabra'
wanted = 'a'

print(stringsearch(string, wanted))

# -----------

# Und hier die Variante als nicht-Funktion:

string = 'abrakadabra'
wanted = 'a'



counter = 0
loop = 1
analyze = string
analyze.find(wanted)
if string.find(wanted) < 0:
loop = 0

while loop == 1:
if analyze.find(wanted) >= 0:
counter += 1
cursor = analyze.find(wanted) + 1
analyze = analyze[cursor:]
else:
break

print(counter)

# edit: Verdammte Einrückungen -.- Warum werden die nicht übernommen??
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil du dazu die Code-Auswahl-Box benutzen musst. Direkt ueber dem Editor-Fenster.
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

Ahh okay, vielen dank ^^

Code: Alles auswählen

def stringsearch(st, wan):

    counter = 0
    loop = 1
    analyze = st
    analyze.find(wan)
    if st.find(wan) < 0:
        loop = 0

    while loop == 1:
        if analyze.find(wan) >= 0:
            counter += 1
            cursor = analyze.find(wan) + 1
            analyze = analyze[cursor:]
        else:
            break

    print(counter)

string = 'abrakadabra'
wanted = 'a'

print(stringsearch(string, wanted))

# -------------


counter = 0
loop = 1
analyze = string
analyze.find(wanted)
if string.find(wanted) < 0:
    loop = 0

while loop == 1:
    if analyze.find(wanted) >= 0:
        counter += 1
        cursor = analyze.find(wanted) + 1
        analyze = analyze[cursor:]
    else:
        break

print(counter)

__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na du gibst ja nix zurueck in deiner Funktion, sondern printest gleich das Ergebnis aus. Das ist schon mal ein schlechtes Design, denn vielleicht willst du das ja gar nicht ausdrucken, sondern irgendwie weiterverarabeiten...

Und weil du kein return hast, gibt Python implizit "None" zurueck, und da du das ebenfalls nochmal printest, druckt Python eben "None" aus.

Der beste Weg waere also, das Ergebnis mit return zurueck zu geben.

Und dann ist da noch der Code selbst. Du machst da eine ganze Reihe von Fehlern oder unnoetigen Dingen:

- analyze = st - wozu? Wenn du das analyze nennen willst, dann nenn doch den parameter so. Eine Kopie brauchst du jedenfalls NICHT, in Python sind Strings immutable, und der String auf Aufrufer-Seite bleibt ganz. Wenn das nicht so waere, wuerde deine Zuweisung das auch nicht aendern - a = b macht in Python keine Kopie, sonder laesst a nur auf das gleiche Objekt zeigen, auf das b schon zeigt. Siehe

Code: Alles auswählen

b = [10]
a = b
b.append(20)
print(b)
- analyze.find(wan) einfach so hingeschrieben verwirft das Ergebnis und ist entsprechend sinnlos.
- statt die ganze Zeit deinen string zu beschneiden, nutz einfach das pos-Argument von find, um dich im String voran zu arbeiten.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Joshuah992: Du hast eine Funktion ohne Rückgabewert geschrieben, gibst diesen aber am Schluß mit `print` aus. Funktion ohne Rückgabewert heißt unter Python, der Rückgabewert ist `None`. Gibt counter mit `return counter` zurück, statt ihn auszugeben.

Du weißt das es `str.count` gibt?

Willst Du es trotzdem selbst programmieren, hier noch ein paar Tipps:
- eine Funktion (`find`) aufzurufen, und mit dem Rückgabewert nichts zu machen, ist unsinnig.
- eine while-Schleife die entweder nie oder unendlich ausgeführt wird, sollte man explizit als if und unendliche Schleife schreiben:

Code: Alles auswählen

def stringsearch(st, wan):
    counter = 0
    analyze = st
    if st.find(wan) < 0:
        loop = 0
    else:
        loop = 1

    if loop == 1:
        while True:
            if analyze.find(wan) >= 0:
                counter += 1
                cursor = analyze.find(wan) + 1
                analyze = analyze[cursor:]
            else:
                break

    return counter
oder weil bei Dir es eigentlich schon eine Abbruchbedingung gibt:

Code: Alles auswählen

def stringsearch(st, wan):
    counter = 0
    analyze = st
    if st.find(wan) < 0:
        loop = 0
    else:
        loop = 1

    if loop == 1:
        while analyze.find(wan) >= 0:
            counter += 1
            cursor = analyze.find(wan) + 1
            analyze = analyze[cursor:]

    return counter
Jetzt siehst Du, dass die `loop` Bedingung und die Abbruchbedingung identisch sind, so dass `loop` eigentlich überflüssig ist:

Code: Alles auswählen

def stringsearch(st, wan):
    counter = 0
    analyze = st
    while analyze.find(wan) >= 0:
        counter += 1
        cursor = analyze.find(wan) + 1
        analyze = analyze[cursor:]
    return counter
Jetzt ist das Umbenennen von `st` in `analyze` eigentlich überflüssig. `find` hat als zweites Argument eine Startposition, so dass das Zurechtschneiden Deines Strings unnötig ist. Du rufst für jeden Druchgang zwei mal find auf, was Rechenzeitverschwendung ist:

Code: Alles auswählen

def stringsearch(st, wan):
    counter = 0
    cursor = 0
    while True:
        cursor = st.find(wan, cursor) + 1
        if cursor <= 0:
            break
        counter += 1
    return counter
Jetzt hast Du eine while-Schleife mit Zähler, die man auch in eine for-Schleife mit `count` umwandeln könnte

Code: Alles auswählen

from itertools import count

def stringsearch(st, wan):
    cursor = 0
    for counter in count():
        cursor = st.find(wan, cursor) + 1
        if cursor <= 0:
            break
    return counter
Joshuah992
User
Beiträge: 16
Registriert: Samstag 3. März 2018, 13:27

Okay, interessant. Vielen Dank für das feedback.

Edit: Danke Sirius3 für die ausführliche Antwort! Hätte nicht gedacht, dass das so schnell geht ^.^ Hab mich immer gefragt, wozu es dieses "return"-Schlüsselwort gibt...
Antworten