for bla in None...

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.
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

for bla in None...

Beitragvon template » Donnerstag 22. November 2007, 09:07

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
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Donnerstag 22. November 2007, 09:41

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.
Zuletzt geändert von CM am Donnerstag 22. November 2007, 11:02, insgesamt 1-mal geändert.
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 09:58

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?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 22. November 2007, 10:06

Hallo!

Code: Alles auswählen

for bla in FunctionThatCouldReturnNone() or []:
    ...

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Beitragvon BlackJack » Donnerstag 22. November 2007, 10:16

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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Donnerstag 22. November 2007, 10:51

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
template
User
Beiträge: 29
Registriert: Mittwoch 21. November 2007, 09:44

Beitragvon template » Donnerstag 22. November 2007, 11:42

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.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 22. November 2007, 11:55

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Beitragvon BlackJack » Donnerstag 22. November 2007, 13:49

@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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Freitag 23. November 2007, 10:28

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Dakre
User
Beiträge: 16
Registriert: Dienstag 13. Juni 2006, 22:40

Beitragvon Dakre » Montag 26. November 2007, 13:27

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...

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder