2017-01-29 4 views
-1

Ich möchte, eine Funktion schreiben, die x ganze Zahlen erfolgt, y, L und R als Parameter und gibt, wenn Truex**y im Intervall (L, R] und False anderweitig.Am effizientesten if-Anweisung?

ich mehrere Möglichkeiten, überlege mir eine bedingte Anweisung in dieser Funktion zu schreiben:

  1. if L < x ** y <= R:
  2. if x ** y > L and x ** y <= R:
  3. if x ** y in range(L + 1, R + 1):

Warum ist die Option 1, die effizienteste in Bezug auf die Ausführung Zeit ?

+1

Haben Sie daran gedacht, es zu testen? 1 wäre eindeutig effizienter als 2, da "x ** y" nur einmal ausgewertet wird, und ich würde annehmen, dass der Aufruf "Bereich" in 3 es langsamer machen würde, wenn Sie es nicht ausrechnen könnten, aber ** Sie könnten dies bestätigen **, mit z "Zeit". – jonrsharpe

+0

Hast du eine Zeitmessung gemacht? – MSeifert

+0

da alle 3 sind nicht zu kompliziert zu implementieren Ich werde sie alle versuchen und überprüfen Sie die Ergebnisse –

Antwort

4

Beide vermeiden # 1 und # 3 x ** y neu berechnet, wobei # 2 zweimal berechnen muss.

Auf Python 2, # 3 wird schrecklich sein, weil es den gesamten Inhalt der range berechnen muss. Auf Python 3.2+, muss es nicht (range ist smart, und kann mathematisch korrekt bestimmen, ob eine int in der range erscheint, ohne tatsächlich zu iterieren, in konstanter Zeit), aber es ist bestenfalls gleich # 1, seit der Erstellung der range Objekt hat überhaupt etwas Overhead.

Wie tobias_k erwähnt in den Kommentaren, wenn x ** y ein float erzeugt, # 3 wird langsamer sein (unterbricht den Python 3.2 + O(1) Mitgliedschaft Testoptimierung, eine implizite Schleife über alle Werte erfordern), und andere Ergebnisse als # 1 erhalten und # 2, wenn der Wert keinem int Wert in range entspricht. Das heißt, das Testen 3.5 in range(1, 5) gibt False zurück und muss 3.5 gegen 1, 2, 3 und 4 einzeln überprüfen, bevor es Ihnen sogar so viel sagen kann.

Im Grunde, bleiben Sie auf # 1, es wird die einzige sein, die redundante Berechnungen vermeidet und vermeidet, eine Tonne von Werten für den Vergleich auf Py 2 und Py3 zu erstellen. # 3 wird nicht viel (wenn überhaupt) langsamer auf Python 3.2+ sein, aber es beinhaltet das Erstellen eines range Objekts, das hier nicht benötigt wird, und wird nicht ganz logisch äquivalent sein.

1

Der erste Teil hat x**y nur einmal zu bewerten, so sollte es schneller sein, als die zweite (auch besser lesbar). Der dritte müsste den Iterator durchlaufen (in Python 2, also sollte er langsamer sein als beide) oder zwei Vergleiche machen (in Python 3, also nicht besser als der erste). Behalte den ersten.

+0

Es ist nur in python2, dass 'range' eine Liste erstellt. In Python3 ist es nicht so schlimm (aber immer noch schlimmer als die anderen beiden) – MSeifert

+1

Die dritte beinhaltet keine Art von impliziten Schleife auf modernen Python 3.2+ ('Bereich' ist schlauer als das auf Py3.2 +), aber Ihre Gesamtschlussfolgerung ist richtig; # 1 wird jede andere Lösung in einer Python-Version gewinnen oder zumindest binden. – ShadowRanger

+0

Ok, bearbeitete Antwort –

Verwandte Themen