2 Stimmen

if-, elif- und else-Kette funktionieren nicht richtig?

Ich arbeite mich gerade durch 'Learn Python the Hard Way' und bin auf ein Hindernis gestoßen. Das Buch gibt einen Einheitstest vor und fordert Sie auf, eine Funktion zu schreiben, die die Tests erfüllt. Aber wenn ich diese Funktion in die interaktive Shell importiere, um sie zu testen, gibt jede Eingabe "direction" zurück und ich kann nicht herausfinden, warum.

Hier ist mein Code:

def pos(item):
    """ Get part of speech for item. """
    pos = ''
    if item == 'north' or 'south' or 'east':
        return 'direction'
    elif item == 'go' or 'kill' or 'eat':
        return 'verb'
    elif item == 'the' or 'in' or 'of':
        return 'stop'
    elif item == 'bear' or 'princess':
        return 'noun'
    else:
        try:
            int(item)
            return 'number'
        except ValueError:
            return 'error'

8voto

Tamás Punkte 45697

Das hätten Sie schreiben sollen:

if item == 'north' or item == 'south' or item == 'east':

oder alternativ dazu:

if item in ('north', 'south', 'east'):

Das Gleiche gilt für die übrigen Zweige.

Um zu erklären, warum Ihr ursprünglicher Code fehlgeschlagen ist, betrachten Sie, wie Python den folgenden Ausdruck parst:

item == 'north' or 'south' or 'east'

Python geht folgendermaßen vor (beachten Sie die Klammern, die die Reihenfolge des Parsens angeben):

(item == 'north') or 'south' or 'east'

Sie haben hier drei Unterausdrücke. item == 'north' wird wahrscheinlich falsch sein (es sei denn, Sie haben zufällig 'north' ). Allerdings, 'south' o 'east' ist, wenn es in einem booleschen Kontext (d. h. einer Bedingung) ausgewertet wird, immer True so dass Sie am Ende mit (item == 'north') or True or True was natürlich eine True .

4voto

Katriel Punkte 115208

Sie verwenden or falsch. Es sollte sein

if item == 'north' or item == 'south' or item == 'east':

oder, idiomatischer ausgedrückt,

if item in ('north', 'south', 'east')

Der Grund für diese Fehlermeldung liegt in der Art und Weise, wie Python die Klammern in den Ausdruck setzt. Man könnte meinen, es macht

if item == ('north' or 'south' or 'east')

aber was tatsächlich passiert ist, ist

if (item == 'north') or ('south') or ('east')

und 'south' eine nicht leere Zeichenkette ist, ist immer True . (Obwohl Ersteres auch nicht funktionieren würde, weil 'north' or 'south' or 'east' wird bewertet nach 'east' aufgrund der Art und Weise, wie Python Kurzschlüsse verursacht or . Aber das ist komplizierter und Sie müssen sich nicht darum kümmern).


Im Übrigen könnten Sie die folgende Redewendung bevorzugen, obwohl Ihre genauso gut ist.

items = {}
items['north'] = items['south'] = items['east'] = 'direction'
items['go'] = items['kill'] = items['eat'] = 'verb'
items['the'] = items['in'] = items['of'] = 'stop'
items['bear'] = items['princess'] = 'noun'

try:
    return items[item]
except KeyError:
    pass

try:
    int(item)
except ValueError:
    pass
else:
    return 'number'

return 'error'

1voto

phihag Punkte 261131
if item == 'north' or 'south' or 'east':

bestimmt den Wahrheitswert von allem, was zwischen den Oder-Zeichen steht. Nicht leere Zeichenketten haben den Wahrheitswert Wahr, so dass die Eingabe 'west' dies zu bewerten:

if False or True or True:

Stattdessen wollen Sie

if item == 'north' or item == 'south' or item == 'east':

oder eher pythonisch:

if item in ('north', 'south', 'east'):

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X