Seite 1 von 1

for bla in None...

Verfasst: Donnerstag 22. November 2007, 09:07
von template
Hi,

manche funktionen liefern eine Liste von Treffern zurück, und wenn es keine Treffer gab None. Jetzt würde ich gern direkt schreiben:

Code: Alles auswählen

for bla in FunctionThatCouldReturnNone():
anstatt:

Code: Alles auswählen

result = FunctionThatCouldReturnNone()
if not result is none:
  for bla in result:
weil ich auf den Fall, das es keine Ergebnisse gibt nicht speziell reagieren will. Er soll dann einfach die Schleife nicht durchlaufen. Gibt es irgendeinen Shortcut um das zu formulieren?

danke im voraus
template

Verfasst: Donnerstag 22. November 2007, 09:41
von CM
Hoi,

der zweite Ansatz ist falsch.

Code: Alles auswählen

if result: # entspricht: if result == True:
wäre korrekt.

Aber stattdessen kannst Du auch mit try ... except ... arbeiten: http://docs.python.org/tut/node10.html

Gruß,
Christian

edit: Leerzeichen eingefügt, so daß URL anzuklicken ist.

Verfasst: Donnerstag 22. November 2007, 09:58
von template
Warum ist der zweite Ansatz falsch? Kann ich ein Objekt nicht mit none vergleichen? Oder bindet der not zu stark und die Auswertungsreihenfolge ist anders als:

not (object is None)

gut, ich habe inzwischen gesehen das es wohl auch einen is not operator gibt, also

object is not None

aber ich fand es in C/C++ schon immer nicht allzu schön, einen nicht boolschen wert für einen if zu verwenden. Also kann ich eine Objektreferenz auch als bool betrachten oder gibt es wirklich einen if [bool] und einen if [object] operator?

Verfasst: Donnerstag 22. November 2007, 10:06
von gerold
Hallo!

Code: Alles auswählen

for bla in FunctionThatCouldReturnNone() or []:
    ...
mfg
Gerold
:-)

Verfasst: Donnerstag 22. November 2007, 10:16
von BlackJack
Welche Funktionen verhalten sich denn so? Falls es selbstgeschriebene sind sollte man das besser ändern. Ansonsten mal dem Autor auf die Füsse treten und fragen was er sich dabei gedacht hat.

@Edit: ``if obj:`` bedeuted ``if bool(obj)``, und ob ein Objekt "wahr" oder "falsch" ist, kann es selbst bestimmen. Entweder mittels `__nonzero__()` oder `__len__()`. Näheres in der Doku.

Gerold's Vorschlag mit dem ``or`` kann also in "komischen" Fällen in die Hose gehen, wenn nämlich die Funktion etwas zurückliefert, das zwar "iterable" aber trotzdem "falsch" ist.

Verfasst: Donnerstag 22. November 2007, 10:51
von CM
Hoi,

ok, Gerold hat noch eine andere Alternative (, die ich nicht so toll finde, aber das ist Geschmackssache). Und BJs Einwand ist ebenfalls einen Gedanken wert.
template hat geschrieben:Warum ist der zweite Ansatz falsch?
Weil:

Code: Alles auswählen

>>> not None
True
>>> none
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'none' is not defined
D. h. mit Deinem "not result" negierst Du, was Du überprüfen willst und "none" gibt es nicht. Der Fehler liegt also in Logik und Syntax.
Korrekt, aber unnötig kompliziert wäre:

Code: Alles auswählen

if result is not None:
Gruß,
Christian

Verfasst: Donnerstag 22. November 2007, 11:42
von template
Ah, ja die Zeile von gerold ist das was ich gesucht habe;) Danke schön. Ich finde das irgendwie blöde, für so etwas gleich 3 Zeilen codieren zu müssen, aber ob das guter Stil ist ist wohl ne Streitfrage. So wie ich das mitbekommen habe versucht man ja in Python möglichst einfach zu bleiben.

Also eine Funktion die das Macht ist findall bei einer Regular Expression. Wie hätte sie denn sinnvoller weise reagieren können? Wäre es besser hier eine leere Liste zurück zu liefern? Den ich habe dieses verhalten jetzt auch in ein paar meiner Funktionen übernommen.

Verfasst: Donnerstag 22. November 2007, 11:55
von gerold
BlackJack hat geschrieben:``or`` kann also in "komischen" Fällen in die Hose gehen
Hallo!

Wenn die Funktion ``None`` statt einer leeren Liste zurück liefert, dann reagiert man entsprechend darauf. Man muss doch nicht immer jeden "komischen" Fall abdecken.

lg
Gerold
:-)

Verfasst: Donnerstag 22. November 2007, 13:49
von BlackJack
@template: Bei mir macht die Funktion das nicht:

Code: Alles auswählen

In [198]: re.findall('x', 'zzz')
Out[198]: []
Die entsprechende Methode auf kompilierten Ausdrücken liefert auch eine leere Liste. Das ist auch definitiv die bessere Lösung als ein extra "Fehlerwert" auf den man dann überall testen müsste. Das so etwas lästig ist, hast Du ja selbst gemerkt.

Verfasst: Freitag 23. November 2007, 10:28
von birkenfeld
template hat geschrieben: aber ich fand es in C/C++ schon immer nicht allzu schön, einen nicht boolschen wert für einen if zu verwenden. Also kann ich eine Objektreferenz auch als bool betrachten oder gibt es wirklich einen if [bool] und einen if [object] operator?
Um das nochmal aufzugreifen: In Python wird es als guter Stil betrachtet die Tatsache auszunutzen, dass die meisten Objekte einen sinnvollen booleschen Wert haben. Zum Beispiel ist

Code: Alles auswählen

if liste != []:
oder

Code: Alles auswählen

if len(liste) > 0:
sowohl langsamer als auch unschöner als das treffende

Code: Alles auswählen

if liste:
Ebenso sieht es mit dicts, strings, tuples und den anderen eingebauten Typen aus. Wie BlackJack schon sagte, kann man auch eigenen Typen solch ein Verhalten einfachst beibringen.

Verfasst: Montag 26. November 2007, 13:27
von Dakre
CM hat geschrieben:Hoi,

ok, Gerold hat noch eine andere Alternative (, die ich nicht so toll finde, aber das ist Geschmackssache). Und BJs Einwand ist ebenfalls einen Gedanken wert.
template hat geschrieben:Warum ist der zweite Ansatz falsch?
Weil:

Code: Alles auswählen

>>> not None
True
>>> none
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'none' is not defined
D. h. mit Deinem "not result" negierst Du, was Du überprüfen willst und "none" gibt es nicht. Der Fehler liegt also in Logik und Syntax.
Korrekt, aber unnötig kompliziert wäre:

Code: Alles auswählen

if result is not None:
Gruß,
Christian
beim zweiten Versuch hast du "None" mit kleinem n geschrieben... das gibt es nicht, im gegensatz zu "None" mit großen N... wenn du also stattdessen bool(None) verwendest, ist der Rückgabewert False...