Prüfen ob ein Wert grösser oder gleich, vorgegebenen Werten ist und dann entsprechend eine Rückgabe erhalten?
Sehr geehrtes Forum.
Guten Morgen und anbei mein erster "Frage"-Beitrag.
Wie kann ich die Frage im Titel in Python elegant lösen?
Anbei ein Beisiel:
Wert (56):
>= 80 => Rückgabewert 1
>= 70 => Rückgabewert 2
....
(else => Rückgabewert n) <= die ist "nice to have"
Mit x-if Abfragen kann ich es lösen, ich hoffe das es schickere Varianten gibt.
Für euere Hilfe bedanke ich mich herzlich.
Freundliche Grüsse
Daniel
Guten Morgen und anbei mein erster "Frage"-Beitrag.
Wie kann ich die Frage im Titel in Python elegant lösen?
Anbei ein Beisiel:
Wert (56):
>= 80 => Rückgabewert 1
>= 70 => Rückgabewert 2
....
(else => Rückgabewert n) <= die ist "nice to have"
Mit x-if Abfragen kann ich es lösen, ich hoffe das es schickere Varianten gibt.
Für euere Hilfe bedanke ich mich herzlich.
Freundliche Grüsse
Daniel
-
- User
- Beiträge: 42
- Registriert: Sonntag 29. September 2019, 12:36
Hallo,
ich denke auch, die if-Geschichte ist hier durchaus geeignet.
So zum Beispiel:
Wenn du dann z.B.
eingibst, gibt dir die Funktion zurück, ob dein Wert (hier 50) größer/ gleich deinem Vergleichswert (hier 80) ist.
In der Hoffnung, deine Frage richtig verstanden zu haben...
Chris
ich denke auch, die if-Geschichte ist hier durchaus geeignet.
So zum Beispiel:
Code: Alles auswählen
def groesser_gleich(wert,vergleichswert):
if wert >= vergleichswert:
return True
else:
return False
Code: Alles auswählen
groesser_gleich(50,80)
In der Hoffnung, deine Frage richtig verstanden zu haben...
Chris
- __blackjack__
- User
- Beiträge: 13241
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@christheturtle: Der Vergleich beim ``if`` wird ja bereits zu einem Wahrheitswert ausgewertet. *Den* kann man auch einfach als Ergebnis liefern:
Damit fängt die Funktion dann aber an wenig Sinn zu machen, weil man diesen Ausdruck jetzt nicht unbedingt in eine Funktion auslagern muss, denn eine Funktion `groesser_gleich()` zu haben ist eher nicht verständlicher oder kürzer als gleich die Operation an der Aufrufstelle zu verwenden.
Sollte man aus Gründen diesen Operator als Funktion benötigen, muss man sich das nicht selbst schreiben, denn alle Operatoren als Funktion gibt es bereits in der Standardbibliothek im `operator`-Modul:
@dll-live: Du könntest Grenzwerte und Ergebnis als Tupel zusammenfassen und in einer Liste stecken und eine Schleife über diese Paare schreiben, in der dann getestet und ggf. ”returned” wird.
Code: Alles auswählen
def groesser_gleich(wert, vergleichswert):
return wert >= vergleichswert
Sollte man aus Gründen diesen Operator als Funktion benötigen, muss man sich das nicht selbst schreiben, denn alle Operatoren als Funktion gibt es bereits in der Standardbibliothek im `operator`-Modul:
Code: Alles auswählen
from operator import ge as groesser_gleich
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
@dll-live: so etwas muß man selbst programmieren, z.B. mit einem Wörterbuch
Code: Alles auswählen
TABLE = {
80: "Rückgabewert 1",
70: "Rückgabewert 2",
50: "Rückgabewert 3",
}
DEFAULT = "nice to have"
def test(value):
for boundary, return_value in sorted(TABLE.items(), reverse=True):
if value >= boundary:
return return_value
return DEFAULT
Hallo zusammen.
Besten Dank für die Antworten!
Nun der Reihe nach:
Warum nicht x-if Abfragen benutzen? => Weil es mir widerstrebt, und ich es schöner finde wenn alles an einem Ort (untereinander) definiert ist, so habe ich meiner Meinung nach auch mehr Übersicht.
Der Code Schnipsel von @Sirius3 ist das wonach ich gesucht habe. => Besten Dank!
Für was wird das Programm verwendet?
Mit Hilfe zweier Eingaben (Gewicht (in Kn), und maximale Bremskraft (ebenfalls Kn)) wird das Verhältnis berechnet, anschliessend über über diese (gesuchte Funktion) das Passendstes (vorhandene Verhältnis) rausgesucht und die weiteren Parameter eingestellt, damit Bremsversuche gemacht werden können.
Nochmals herzlichen Dank,an alle die sich an der Lösungsfindung beteiligt haben.
Freundliche Grüsse
Daniel
Besten Dank für die Antworten!
Nun der Reihe nach:
Warum nicht x-if Abfragen benutzen? => Weil es mir widerstrebt, und ich es schöner finde wenn alles an einem Ort (untereinander) definiert ist, so habe ich meiner Meinung nach auch mehr Übersicht.
Der Code Schnipsel von @Sirius3 ist das wonach ich gesucht habe. => Besten Dank!
Für was wird das Programm verwendet?
Mit Hilfe zweier Eingaben (Gewicht (in Kn), und maximale Bremskraft (ebenfalls Kn)) wird das Verhältnis berechnet, anschliessend über über diese (gesuchte Funktion) das Passendstes (vorhandene Verhältnis) rausgesucht und die weiteren Parameter eingestellt, damit Bremsversuche gemacht werden können.
Nochmals herzlichen Dank,an alle die sich an der Lösungsfindung beteiligt haben.
Freundliche Grüsse
Daniel
Also suchst du eigentlich den nächstgelegenen Wert? Das kann man zB so machen:
Code: Alles auswählen
from operator import itemgetter
VALUES = [80, 70, 55, 40, 25, 15, 10, 5]
def find_best_value(x, values):
deltas = [(i, abs(x - v)) for i, v in enumerate(values)]
index, _ = min(deltas, key=itemgetter(1))
return values[index]
print("Bester Wert:", find_best_value(42, VALUES))
- DeaD_EyE
- User
- Beiträge: 1037
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Man kann es noch auf die Spitze treiben.
Wenn man z.B. ein Mapping mit Lücken hat, muss man ein oberes und unteres Limit definieren können.
Oder man nimmt etwas Fertiges: https://pypi.org/project/rangedict/
Wenn man z.B. ein Mapping mit Lücken hat, muss man ein oberes und unteres Limit definieren können.
Code: Alles auswählen
TABLE = {
(0, 10): "Foo1",
# hier ist eine Lücke
(14, 20): "Foo2",
# hier auch
(22, 23): "Foo3",
(23, 24): "Foo4",
}
DEFAULT = "Wert ist nicht im Bereich"
def bereich(wert):
for (lower, upper), text in TABLE.items():
if lower <= wert < upper:
return text
else:
return DEFAULT
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
@snafu: warum speichert Du den Index in der Liste, wenn Du später sowieso den Wert möchtest?
oder gleich als key-Funktion:
Code: Alles auswählen
from operator import itemgetter
VALUES = [80, 70, 55, 40, 25, 15, 10, 5]
def find_best_value(x, values):
deltas = [(v, abs(x - v)) for v in values]
value, _ = min(deltas, key=itemgetter(1))
return value
print("Bester Wert:", find_best_value(42, VALUES))
Code: Alles auswählen
def find_best_value(x, values):
return min(values, key=lambda v: abs(x - v))
Sieht sehr gut aus. War doch klar, dass es auch als Einzeiler möglich ist.Sirius3 hat geschrieben: ↑Mittwoch 12. August 2020, 16:18Code: Alles auswählen
def find_best_value(x, values): return min(values, key=lambda v: abs(x - v))
Hier die Variante mit Mindestwerten als Einzeiler.
Code: Alles auswählen
reduce(lambda a,b: a if a <= x < b else b, sorted(values))
Es gab bei mir noch ein Problem, wenn x kleiner als der niedrigste Wert war. Dann wurde immer der höchste Wert als Ergebnis geliefert. Mit der folgenden Zeile ist dieses Verhalten geändert. Wenn hier x "zu klein" ist, wird der niedrigste Wert angenommen. Analog dazu der höchste, wenn x größer als alle anderen Werte ist.
Code: Alles auswählen
reduce(lambda a, b: a if x >= a else b, sorted(values, reverse=True))
Hallo Zusammen.
Besten Dank für die weiteren Antworten.
@snafu: Ich suche nicht einfach den nächst passenden Wert sondern den nächst tieferen passenden wert. (zb.: 80 bei 89 und nicht 90)
@DeaD_EyE: Besten Dank für dein Beispiel. Im Anwendungsfall gibt es keine Lücken. (Das ist zu 100% ausgeschlossen)
Freundliche Grüsse
Daniel
Besten Dank für die weiteren Antworten.
@snafu: Ich suche nicht einfach den nächst passenden Wert sondern den nächst tieferen passenden wert. (zb.: 80 bei 89 und nicht 90)
@DeaD_EyE: Besten Dank für dein Beispiel. Im Anwendungsfall gibt es keine Lücken. (Das ist zu 100% ausgeschlossen)
Freundliche Grüsse
Daniel
Wenn Du den nächst kleineren Wert suchst, dann wäre das
Code: Alles auswählen
def find_best_value(x, values):
return max(v for v in values if x>v)
Um die Anregung mit bisect mal zu übernehmen:
Wirklich schneller dürfte das aber nicht sein, solange die Breakpoints überschaubar bleiben. Kann man aber natürlich alles messen, wenn man möchte. Würde ich aber nur dann tun, wenn sich der Vorgang wirklich langsam anfühlt. Das bisect-Modul ist halt auch "nur" in reinem Python programmiert und an sich für andere Anwendungsfälle konzipiert.
PS: sorted() ist nur zur Sicherheit eingebaut. Wenn die Breakpoints schon sortiert vorliegen, wie bei dem Test, dann ist es unnötig. Die Implementierung für's Sortieren in Python bricht zum Glück schnell ab, wenn sie erkennt, dass bereits sortierte Werte vorliegen. Somit hält sich der Mehraufwand in Grenzen.
Code: Alles auswählen
from bisect import bisect
def get_breakpoint(value, breakpoints):
index = bisect(sorted(breakpoints), value)
if not index:
raise ValueError("Did not match any breakpoint")
return breakpoints[index - 1]
breakpoints = [10, 15, 20, 30, 50, 70, 100]
for value in (11, 20, 29, 101, 4):
print(get_breakpoint(value, breakpoints))
PS: sorted() ist nur zur Sicherheit eingebaut. Wenn die Breakpoints schon sortiert vorliegen, wie bei dem Test, dann ist es unnötig. Die Implementierung für's Sortieren in Python bricht zum Glück schnell ab, wenn sie erkennt, dass bereits sortierte Werte vorliegen. Somit hält sich der Mehraufwand in Grenzen.
-
- User
- Beiträge: 42
- Registriert: Sonntag 29. September 2019, 12:36
Guter Hinweis, Danke!__blackjack__ hat geschrieben: ↑Dienstag 11. August 2020, 11:35 @christheturtle: Der Vergleich beim ``if`` wird ja bereits zu einem Wahrheitswert ausgewertet. *Den* kann man auch einfach als Ergebnis liefern:Damit fängt die Funktion dann aber an wenig Sinn zu machen, weil man diesen Ausdruck jetzt nicht unbedingt in eine Funktion auslagern muss, denn eine Funktion `groesser_gleich()` zu haben ist eher nicht verständlicher oder kürzer als gleich die Operation an der Aufrufstelle zu verwenden.Code: Alles auswählen
def groesser_gleich(wert, vergleichswert): return wert >= vergleichswert
Sollte man aus Gründen diesen Operator als Funktion benötigen, muss man sich das nicht selbst schreiben, denn alle Operatoren als Funktion gibt es bereits in der Standardbibliothek im `operator`-Modul:@dll-live: Du könntest Grenzwerte und Ergebnis als Tupel zusammenfassen und in einer Liste stecken und eine Schleife über diese Paare schreiben, in der dann getestet und ggf. ”returned” wird.Code: Alles auswählen
from operator import ge as groesser_gleich