Python optimiert selbstständig?

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.
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Sonntag 23. Juli 2006, 19:50

Beim Profilen ( verwende ich zum Durchzählen ob die Rekursion auch wirklich passt ) meines Backtracking Scripts bin ich auf etwas sonderbares gestoßen.
Kann es sein das Python IF's automatisch optimiert?

Code: Alles auswählen

a = 0
b = 1
c = 1

if ( a and b and c )
Nun wird er in meinem Beispiel b und c niemals auf true prüfen. Hab ich das richtig erkannt? Falls es doch nicht so ist hab ich glaub ich ein Problem :D

lg tlb

p.s. der code tag ist praktisch :)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Sonntag 23. Juli 2006, 20:48

thelittlebug hat geschrieben:

Code: Alles auswählen

a = 0
b = 1
c = 1

if ( a and b and c )
Nun wird er in meinem Beispiel b und c niemals auf true prüfen. Hab ich das richtig erkannt?
Hi!

Du hast das schon richtig verstanden. Das ist bei Python das normale Verhalten.

Da der Ausdruck ``a and b and c`` nur dann True ergeben kann, wenn ``a``, ``b`` und ``c`` True sind, genügt das erste Auftreten eines False-Ausdrucks um die Prüfung abzubrechen und ein False zurück zu geben. Du hast recht. ``b`` und ``c`` werden nicht mehr ausgewertet, da ``a`` bereits False ist.

Es ist sogar so, dass nicht wirklich ein ``False`` zurück gegeben wird, sondern der Wert des ersten Ausdrucks, der für den Abbruch der Prüfung gesorgt hat.

Code: Alles auswählen

>>> a = 0
>>> b = 1
>>> c = 2
>>> a and b and c
0
>>> b and c
2
>>> 
http://docs.python.org/lib/boolean.html

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

Sonntag 23. Juli 2006, 21:18

Kleines unwichtiges Detail noch: Nicht das ``if`` wird optimiert, sondern ``and`` und ``or``.
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Sonntag 23. Juli 2006, 22:00

Danke für die Aufklärung.

Ich dachte schon ich seh nicht richtig :)
Am Anfang ist man halt bereits mit/durch kleinem/s überfordert

mfg tlb
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Sonntag 23. Juli 2006, 23:17

Optimiert wird da eigentlich gar nix. Dieses Verhalten ist so spezifiziert und wird wie in vielen Programmiersprachen (also z.B. nicht V.B.) so implementiert, einfach weil es sinnvoll ist. (Stichwort short-circuited boolean evaluation)
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Montag 24. Juli 2006, 12:12

Stichwort short-circuited boolean evaluation
Auch recht häufig gehört: "Lazy evaluation".
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 24. Juli 2006, 12:50

keppla hat geschrieben:Auch recht häufig gehört: "Lazy evaluation".
Das ist aber was ganz anderes. Generatoren sind zum beispiel lazy evaluated, da ihre Werte erst dann zur Verfügung stehen wenn sie gebraucht werden, nicht schon vorher. Vergleiche range() mit xrange().
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Montag 24. Juli 2006, 13:49

was "ganz anderes" würde ich nicht unbedingt sagen. Abstrakt gesprochen heist lazy evaluation afaik, dass man einen baum hat, der ausgewertet werden soll, und dass nur die nötigen zweige betrachtet werden.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Montag 24. Juli 2006, 19:43

Ja, aber gerade das macht Python nicht:

Code: Alles auswählen

def f(x):
 return x**0.4+2*x
liste = [f(x) for x in range(100)]
print liste[50]
Python ruft hier f 100 mal auf. Eine Sprache mit Lazy Evaluation würde nur f(50) aufrufen.

Schau dir z.B. mal Haskell an. Dort kannst du auch ohne Probleme unendlich große Listen, z.B. die Liste aller Primzahlen definieren, weil nur die Elemente ausgewertet werden, die wirklich benötigt werden.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Montag 24. Juli 2006, 19:59

Joghurt hat geschrieben:Dort kannst du auch ohne Probleme unendlich große Listen, z.B. die Liste aller Primzahlen definieren.
Ui! Dann koenntest du nebenbei eventuell noch den Abel-Preis fuer Mathematik einheimsen, weil du der erste waerest, der eine Formel zur Berechnung von Primzahlen gefunden hat. :wink:
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Montag 24. Juli 2006, 20:12

Das hat ein Gewisser Eratosthenes vor über 2000 Jahren gemacht.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dienstag 25. Juli 2006, 07:36

Das, was Eratosthenes gemacht hat, war ein besonders schlauer Algorithmus, aus einem endlichen Intervall [2, n] alle Primzahlen rauszufinden, indem man nach und nach alle nicht-Primzahlen ausschliesst. Es ist die etwas schlauere Variante zu "Teste bei jeder Zahl, ob sie durch irgendwas anderes als eins und sich selbst teilbar ist". Das ganze nennt sich Sieb des Erastosthenes. Es ist aber keine Formel zur Berechnung neuer Primzahlen, und man kann somit nicht unendlich viele Primzahlen angeben (nur beliebig viele).

Nicht umsonst kann man die Freizeit seines Rechners auch zum Berechnen der naechsten unbekannten Primzahl opfern statt zur Suche nach ausserirdischer Intelligenz. Laut Wikipedia ist die groesste zurzeit bekannte Primzahl 2^30402457 − 1. Oh, und ich sehe gerade:
Wikipedia hat geschrieben:Für den ersten Primzahlbeweis einer Zahl mit mehr als 10 Millionen Dezimalstellen hat die Electronic Frontier Foundation einen Preis von 100.000 US-Dollar ausgeschrieben.
Also ranhalten, Leute! :wink:
BlackJack

Dienstag 25. Juli 2006, 09:16

Rebecca hat geschrieben:Das, was Eratosthenes gemacht hat, war ein besonders schlauer Algorithmus, aus einem endlichen Intervall [2, n] alle Primzahlen rauszufinden, indem man nach und nach alle nicht-Primzahlen ausschliesst. Es ist die etwas schlauere Variante zu "Teste bei jeder Zahl, ob sie durch irgendwas anderes als eins und sich selbst teilbar ist". Das ganze nennt sich Sieb des Erastosthenes. Es ist aber keine Formel zur Berechnung neuer Primzahlen, und man kann somit nicht unendlich viele Primzahlen angeben (nur beliebig viele).
Man kann aber problemlos mathematisch bzw. in Haskell eine Liste mit allen Primzahlen definieren. Und nur das hat Joghurt behauptet. Nicht das er eine effiziente Formel zur direkten Berechnung der n-ten Primzahl hat.

Hier ist die Definition des Siebs und der Liste aller Primzahlen in Haskell:

Code: Alles auswählen

sieve (x:xs) = x : sieve [n | n <- xs, mod n x /= 0]
sieve _      = []

all_primes = sieve [2..]
Und im Interpreter sieht's dann so aus:

Code: Alles auswählen

$ ghci primes.hs
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.4.1, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base-1.0 ... linking ... done.
Compiling Main             ( prime.hs, interpreted )
Ok, modules loaded: Main.
*Main> sieve [2..100]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
*Main> all_primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,
83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,
163,167,173,179,181,191,193,197,199,211,223,227,229,233,
239,241,251,257,263,269,271,277,281,283,293,307,311,313,
317,331,337,347,349,353,359,367,373,379,383,389,397,401,
409,419,421,431,433,439,443,449,457,461,463,467,479,487,
...
Das läuft ewig so weiter bis man das Programm abbricht, oder der Speicher aufgebraucht ist.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Dienstag 25. Juli 2006, 20:32

Ja, aber gerade das macht Python nicht
In diesem beispiel nicht, aber da hast du ja auch keine Baumstruktur zugrunde liegen, afaik

aber z.B. in

Code: Alles auswählen

print (False or True) or doCalculation
hat man eine.

Wie gesagt: kommt drauf an, was man unter Lazy Evaluation versteht.
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Dienstag 25. Juli 2006, 20:38

ist nicht alles ein baum?
sogar 1+1?

siehe lisp?

mfg tlb
Antworten