Vereinfachung immerwiederkehrender Ausdruck

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.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Vereinfachung immerwiederkehrender Ausdruck

Beitragvon droptix » Freitag 22. Dezember 2006, 14:27

Kennt ihr sowas auch?

Code: Alles auswählen

a = foo()
if a is not False:
    print a


Ich wünsche mir da manchmal eine verkürzte Form, wo ich a nicht unbedingt erst zwischenspeichern muss, bevor ich a nicht wirklich brauche. Jetzt kommt Pseudo-Code:

Code: Alles auswählen

print a if (a = foo() is not False)
alban
User
Beiträge: 8
Registriert: Mittwoch 19. April 2006, 23:44

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon alban » Freitag 22. Dezember 2006, 15:27

droptix hat geschrieben:Kennt ihr sowas auch?

Code: Alles auswählen

a = foo()
if a is not False:
    print a


Ich wünsche mir da manchmal eine verkürzte Form, wo ich a nicht unbedingt erst zwischenspeichern muss, bevor ich a nicht wirklich brauche. Jetzt kommt Pseudo-Code:

Code: Alles auswählen

print a if (a = foo() is not False)


Dein Punkt ist wahrscheinlich ein anderer, aber was it falsch mit dieser Verkürzung:

Code: Alles auswählen

if foo(): print foo()

Die erste Vereinfachung ist anstatt not False -> True zu testen. Dann nicht erst einer Variable zuordnen, sonder gleich die Funktion nehmen.

Gruß,

Alban
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon droptix » Freitag 22. Dezember 2006, 15:31

alban hat geschrieben:Dein Punkt ist wahrscheinlich ein anderer, aber was it falsch mit dieser Verkürzung:

Code: Alles auswählen

if foo(): print foo()

Die erste Vereinfachung ist anstatt not False -> True zu testen. Dann nicht erst einer Variable zuordnen, sonder gleich die Funktion nehmen.


Na foo() wird zwei Mal ausgeführt. Das muss nicht sein, da bereits der erste Aufruf das gewünschte Ergebnis liefert. Und wenn foo() sehr zeitaufwändig arbeitet und/oder dazu noch in einer Schleife aufgerufen wird, geht das deutlich zu lasten der Performance.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon Leonidas » Freitag 22. Dezember 2006, 15:39

droptix hat geschrieben:Na foo() wird zwei Mal ausgeführt. Das muss nicht sein, da bereits der erste Aufruf das gewünschte Ergebnis liefert. Und wenn foo() sehr zeitaufwändig arbeitet und/oder dazu noch in einer Schleife aufgerufen wird, geht das deutlich zu lasten der Performance.

Oder stellt euch vor foo() gibt die aktuelle Mikrosekunde aus.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon BlackJack » Freitag 22. Dezember 2006, 16:33

droptix hat geschrieben:Kennt ihr sowas auch?

Code: Alles auswählen

a = foo()
if a is not False:
    print a


Das würde ich eher so schreiben:

Code: Alles auswählen

a = foo()
if a:
    print a


Ich wünsche mir da manchmal eine verkürzte Form, wo ich a nicht unbedingt erst zwischenspeichern muss, bevor ich a nicht wirklich brauche. Jetzt kommt Pseudo-Code:

Code: Alles auswählen

print a if (a = foo() is not False)


Das ist jetzt nicht Dein Ernst, oder? Du hast da genau das gleiche geschrieben wie oben, nur in einer anderen Reihenfolge. Was ist daran jetzt vereinfacht? Und das Ergebnis der Funktion wird auch hier "zwischengeschpeichert", nämlich in jedem Fall an `a` gebunden.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon droptix » Samstag 23. Dezember 2006, 12:00

BlackJack hat geschrieben:Das ist jetzt nicht Dein Ernst, oder? Du hast da genau das gleiche geschrieben wie oben, nur in einer anderen Reihenfolge. Was ist daran jetzt vereinfacht? Und das Ergebnis der Funktion wird auch hier "zwischengeschpeichert", nämlich in jedem Fall an `a` gebunden.


Is ja mein Problem, dass ich es gern ohne Zwischenspeichern machen würde, aber nicht weiß wie man das ausdrücken soll :lol: Vielleicht noch so hier:

Code: Alles auswählen

print foo() if not False


Das trifft's vielleicht eher. Dann kann ich aber mit dem Ergebnis nicht weiterarbeiten... Vielleicht noch sowas hier:

Code: Alles auswählen

a = foo() if not False
if a:
    print a


Vielleicht mach ich das aber auch einfach so wie bisher :roll:
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Samstag 23. Dezember 2006, 13:04

Ob mein Vorschlag nun in jedem Fall sinnvoll ist, darüber läßt sich streiten, aber man könnte sich eine hübsche Funktion basteln, die diese Aufgabe übernimmt. Wenn man aber mit Klassen arbeitet (was ja öffter mal vorkommt ;-) ), kann man es aber auch schon wieder wegwerfen:

Code: Alles auswählen

def ifthen(condition, expression):
   if condition:
      return expression(condition)


Aufrufe sehen dann, beispielsweise so aus:

Code: Alles auswählen

def out(spam):
   print spam

   
ifthen(foo(), out)


Oder natürlich schöner mit Lambda-Ausdrücken:

Code: Alles auswählen

ifthen(foo(), lambda x : sys.stdout.write(x))
BlackJack

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon BlackJack » Samstag 23. Dezember 2006, 13:57

droptix hat geschrieben:
BlackJack hat geschrieben:Das ist jetzt nicht Dein Ernst, oder? Du hast da genau das gleiche geschrieben wie oben, nur in einer anderen Reihenfolge. Was ist daran jetzt vereinfacht? Und das Ergebnis der Funktion wird auch hier "zwischengeschpeichert", nämlich in jedem Fall an `a` gebunden.


Is ja mein Problem, dass ich es gern ohne Zwischenspeichern machen würde, aber nicht weiß wie man das ausdrücken soll :lol: Vielleicht noch so hier:

Code: Alles auswählen

print foo() if not False


Das trifft's vielleicht eher. Dann kann ich aber mit dem Ergebnis nicht weiterarbeiten...


Du möchtest es nicht an einen Namen binden, aber später noch darauf zugreifen!? Das widerspricht sich irgendwie.

Code: Alles auswählen

a = foo() if not False
if a:
    print a


Könntest Du davon bitte mal die Semantik erklären? Die erschliesst sich mir gerade so gar nicht. An was ist `a` nach Ausführung der der ersten Zeile gebunden für die Fälle 1) `foo()` gibt `False` zurück und 2) `foo()` gibt etwas ungleich `False` zurück?
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Beitragvon Joghurt » Samstag 23. Dezember 2006, 19:54

Bastel dir doch eine Funktion dafür

Code: Alles auswählen

def do_if_not_false(var, operation):
  if var:
    operation(var)

def mein_print(x):
  print x

do_if_not_false(foo(), mein_print)
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon sape » Samstag 23. Dezember 2006, 20:57

droptix hat geschrieben:

Code: Alles auswählen

a = foo() if not False
if a:
    print a


Verstehe ehrlich auch nicht worauf du hinaus willst.

Möchtest du testen ob `a` eine Instanz von der Klasse `foo`ist?
Dan geht das so:

Code: Alles auswählen

class foo(object):
    pass

x = foo()

if isinstance(x, foo):
    print "x ist Instanz  von foo"
else:
    print "x != Instanz  von foo"

x = 1
if isinstance(x, foo):
    print "x ist Instanz  von foo"
else:
    print "x != Instanz  von foo"

Code: Alles auswählen

x ist Instanz  von foo
x != Instanz  von foo


Folgendes würde aber immer True sein, unabhängig vom Type des Objekts. Daher verstehe ich nicht ganz was genau du willst.

Code: Alles auswählen

class foo(object):
    pass

x = 1
if x:
    print "x ist True"
   
x = foo()
if x:
    print "x ist True"


:?
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Samstag 23. Dezember 2006, 21:04

Es widerspricht sich ein Objekt auf True zu testen weil, in dem Fall auf Existenz hin geteste wird! Der Widerspruch ergibt sich aus folgenden Code:

Code: Alles auswählen

class foo(object):
    pass


if x:
    print "x ist True"
   

if x:
    print "x ist True"

Da wird ne schöne exception ausgelöst weil x nicht existiert.


Andersrum wenn x aber existiert, _egal_ von welchen Type, würde die Überprüfung immer True zurückgeben :? -> Widerspruch. EDIT2: Man kann damit eben doch nicht testen ob `x` existiert, weil bei nicht Existenz eine Exception ausgelöst wird und bei Existenz die Bedingung wahr wird (Was für ein Schwachsinn!! Eine der wenigen Sachen die in Python nicht konsistent sind! :? -> In dem Sinne das bei existenz bei ìf x == True` Tatsächlich wahr wird, obwohl nicht vom Type `Bool`, hmmm....)

Code: Alles auswählen

class foo(object):
    pass

x = 1
if x:
    print "x ist True"
   
x = foo()
if x:
    print "x ist True"

x = "test"
if x:
    print "x ist True"


Nach deinem Code zu urteilen macht dein Beispiel nichts anderes und daher -> Wo liegt der Sinn? :?

Hmm, ich hoffe man kann mir einigermaßen folgen worauf ich hinaus will.

lg
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon droptix » Montag 25. Dezember 2006, 22:44

BlackJack hat geschrieben:Könntest Du davon bitte mal die Semantik erklären? Die erschliesst sich mir gerade so gar nicht. An was ist `a` nach Ausführung der der ersten Zeile gebunden für die Fälle 1) `foo()` gibt `False` zurück und 2) `foo()` gibt etwas ungleich `False` zurück?


Hatte ich vergessen zu erwähnen, dachte es kommt schon korrekt rüber: foo() gibt False zurück, wenn die Prozedur innerhalb von foo() nicht erfolgreich war. Andernfalls liefert foo() einen Wert ungleich False.

Ich hätte die Frage prinzipiell vielleicht anders stellen sollen:

Code: Alles auswählen

if foo() is not False:
    print foo()


Sowas in der Art hatten wir ja oben schon. Nun die Frage: Wie löst man das am besten, wenn man nicht zwei Mal foo() schreiben will, weil foo() dann auch zwei Mal ausgeführt wird?

In PHP gibt's da beispielsweise sowas:

Code: Alles auswählen

<?php
if &#40;($a = foo()) !== false) {
    
echo $a;
&
#125;
?>


Aber eigentlich wird das Ergebnis von foo() dabei auch in $a zwischengespeichert, nur eben gleich in einem Ausdruck.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 26. Dezember 2006, 08:00

*Glaskugelrausholentun*

foo() gibt False zurück, wenn die Prozedur innerhalb von foo() nicht erfolgreich war

Mit Prozedur innerhalb von `foo` willst du also sagen das `Foo` eine Klasse ist? Dan meinst du den Konstruktor. Der Konstruktor kann keinen von dir mit `return` bestimmten Wert zurückliefern, sondern erzeugt eine Instanz von `Foo`.

Darauf bezogen:

Code: Alles auswählen

class Foo(object):
    def __init__(self, filename):
        path = os.path.split(filename)[0]
        if not os.path.exists(path):
            raise IOError(2, "Der angegeben Pfad existiert nicht", path)

try:
    x = Foo("test")
    print "ok"
    print x
except IOError:
    print "nicht ok"
Wenn irgendwas dazu führt das die Instanzierung fehlschlägt, sollte immer eine Exception ausgelöst werden. Was Spricht dagegen?


Oder redest du von einer Funktion die innerhalb wider eine Funktion hat?
Darauf bezogen:

Code: Alles auswählen

def foo(val):
    def tester(val):
        if val != 100:
            return False
        else:
            return True
    return tester(val)

if foo(1):
    print "True"
else:
    print "False"


Wie wäre es wenn du mal deine Implementierungen von `Foo` oder `foo`hier postetst mit einem dazugehörigen Beispiel?? Langsam hört sich das alles sehr widersprüchlich an. Siehe hier: ==>
Hatte ich vergessen zu erwähnen, dachte es kommt schon korrekt rüber: foo() gibt False zurück, wenn die Prozedur innerhalb von foo() nicht erfolgreich war. Andernfalls liefert foo() einen Wert ungleich False.
Warum? `Foo` = Derivat von `bool`? Also es wird eine Instanz von `Foo` in `a` erzeugt das lediglich ein bool Derivat ist? Oder soll der Konstruktor von `Foo` einen Bolschen wert returnen? 0o

Code: Alles auswählen

class Foo(object):
    def __init__(self, val):
        # wenn val nit ok...
        [...]
        return False # Geht nicht!
        # wenn ok
        [...]
        return True # geht auch nicht!

Foo(1)

output:

Code: Alles auswählen

TypeError: __init__() should return None, not 'bool'


Bevor ich ein weiteres mal die Glaskugel raushole, bitte mal konkreter werden! :roll: Zeig mal was genau `Foo`ist :) Danke.

lg
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon sape » Dienstag 26. Dezember 2006, 08:04

droptix hat geschrieben:[...]
Sowas in der Art hatten wir ja oben schon. Nun die Frage: Wie löst man das am besten, wenn man nicht zwei Mal foo() schreiben will, weil foo() dann auch zwei Mal ausgeführt wird?

In PHP gibt's da beispielsweise sowas:

Code: Alles auswählen

<?php
if &#40;($a = foo()) !== false) {
    
echo $a;
&
#125;
?>


Was zum kuckuck spricht den bitte gegen folgendes? :D

Code: Alles auswählen

a=foo()
if a:
    print a
    print "a ist True ;)"
else:
    print a
    print "a ist False ;)"


Sorry, aber ich sehe den Sinn einfach nicht in dieser Frage :K


Schönen rutsch ins neue Jahr und liebe grüße
Sape
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Re: Vereinfachung immerwiederkehrender Ausdruck

Beitragvon droptix » Dienstag 26. Dezember 2006, 12:45

sape hat geschrieben:Mit Prozedur innerhalb von `foo` willst du also sagen das `Foo` eine Klasse ist? Dan meinst du den Konstruktor. Der Konstruktor kann keinen von dir mit `return` bestimmten Wert zurückliefern, sondern erzeugt eine Instanz von `Foo`.


Macht bitte keine Wissenschaft draus... mit foo() meinte ich eine simple Funktion und mit Prozedur die Aufgabe, die die Funktion zu erfüllen hat. Wenn die Aufgabe fehlschlägt (z.B. Division durch Null oder was weiß ich sonst noch), dann liefert die Funktion halt False zurück.

sape hat geschrieben:Oder redest du von einer Funktion die innerhalb wider eine Funktion hat?


Laut Wikipedia wäre eine Prozedur in der Programmierung eine Funktion/Methode, die keinen Rückgabewert erzeugt. Macht auch Sinn... aber der Begriff wäre eng gesehen in meinem Fall falsch gewählt, da ja im Fehlerfall False zurück gegeben wird.

sape hat geschrieben:Bevor ich ein weiteres mal die Glaskugel raushole, bitte mal konkreter werden! :roll: Zeig mal was genau `Foo`ist :) Danke.


Is doch völlig Wurscht. Es ging mir nur um syntaktische Möglichkeiten.

sape hat geschrieben:Was zum kuckuck spricht den bitte gegen folgendes? :D

Code: Alles auswählen

a=foo()
if a:
    print a
    print "a ist True ;)"
else:
    print a
    print "a ist False ;)"


Theoretisch gesehen nichts. Wie gesagt, es ging mir um syntaktische Möglichkeiten.

In einem Fall habe ich ne Funktion ListDir, die mir den Verzeichnisinhalt eines Pfades einliest. Wenn alles klar ging, liefert die Funktion ein Dict zurück. Wenn dabei was schief ging (Pfad falsch, keine Zugriffsrechte etc.), dann eben False:

Code: Alles auswählen

def ListDir(path):
    try:
        c = os.listdir(path)
    except:
        return False
    r = {
        'dirs': [],
        'files': [],
        'links': []
    }
    for i in c:
        item = os.path.join(path, i)
        if os.is_link(item):
            r['links'].append(i)
        elif os.is_dir(item):
            r['dirs'].append(i)
        elif os.is_file(item):
            r['files'].append(i)
    return r


Nun rufe ich ListDir innerhalb einer rekursiven Funktion auf, um jedes Unterverzeichnis zu durchwandern (Code-Ausschnitt):

Code: Alles auswählen

def Walk(path):
    r = ListDir(path)
    if r is not False:
        print path
        for d in r['dirs']:
            Walk(os.path.join(path, d))

Walk("/")


Das ist meine Ausgangsbasis, weil sie so oft hinterfragt wurde... Prinzipiell ist dort auch ein

Code: Alles auswählen

print path if ListDir(path) is not False


versteckt. Wie gesagt: Ich würde den Thread jetzt schließen.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]