Wert und Stelle in Liste suchen

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

Hey Leute hab eine kurze Frage.

Ich möchte aus einer liste die Stelle eines Wertes herausbekommen.

Code: Alles auswählen

ie_ist = 385
ie_array = [250,
            256, 263, 270, 278, 286, 294, 303, 313, 323, 333,
            345, 357, 370, 385, 400, 417, 435, 455, 476, 500, 
            526, 556, 588, 625, 667, 714, 769, 833, 909, 1000,
            1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000,
            2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000,
            3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000]

x = 0
print(ie_ist)
for x in ie_array:
    if ie_ist == ie_array[x]:
        print("ie-ist gefunden =", x)
        return x
    x += 1
Mein ie_ist kann nur die Werte aus dem ie_array annehmen, jetzt will ich das ie_ist mittels der for schleife suchen, wenn es dann gefunden wird will ich, dass mir die Stelle aus dem Array angezeigt wird.

Mein Problem hierbei ist, dass mein Code mir irgendwie immer nur eine 61 ausgibt... also die Stelle des letzten Wertes der liste... Hat da jemand eine Idee warum das so ist?


Grüße
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich bekomme einen SyntaxError, weil `return` außerhalb einer Funktion auftaucht.
Behebt man das, dann bekomme ich einen IndexError, weil 250 ein Index außerhalb der Liste ie_array ist.
Welchen Code führst Du also tatsächlich aus?

x = 0 wird nicht verwendet, weil Du x innerhalb der for-Schleife belegst. Ebenso ist das x+=1 unsinnig, da es gleich im nächsten for-Schleifen-Schritt wieder überschrieben wird.

Dann sind ie_array und ie_ist schlechte Namen, weil das ie ein nichtssagendes Kürzel ist.
array ist auch kein Array sondern eine Liste.
Um einen Index zu suchen, gibt es die Index-Funktion:

Code: Alles auswählen

ie_array.index(ie_ist)
mochtend

Jo hab was vergessen beim Code kopieren... Sorry
Auf die Spur mit dem Index bin ich in der Zwischenzeit auch gekommen.
Aber danke nochmal für deine Rückmeldung 👍👍

Edit: ich kann verstehen dass diese Kürzel nichtssagend erscheinen allerdings sind sie es nur wenn man nicht weiß worum es geht.
Ie = inspiration expiration
Benutzeravatar
DeaD_EyE
User
Beiträge: 1020
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Angenommen die Zahl kommt öfters als einmal vor:

Code: Alles auswählen

ie_ist = 385
ie_array = [250,
    256, 263, 270, 278, 286, 294, 303, 313, 323, 333,
    345, 357, 370, 385, 400, 417, 435, 455, 476, 500, 
    526, 556, 588, 625, 667, 714, 385, 769, 833, 909, 1000,
    1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000,
    2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000,
    3100, 3200, 3300, 3400, 385, 3500, 3600, 3700, 3800, 3900, 4000
]

positions = []
index = 0
while True:
    try:
        index = ie_array.index(ie_ist, index)
    except ValueError:
        break
    else:
        positions.append(index)
        index += 1

print(positions)
Besser wäre es das in eine Funktion zu packen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
mochtend

@DeaD_EyE

Habe es jetzt so gestaltet:

Code: Alles auswählen

ie_array = [250 ,
            256, 263, 270, 278, 286, 294, 303, 313, 323, 333,
            345, 357, 370, 385, 400, 417, 435, 455, 476, 500,
            526, 556, 588, 625, 667, 714, 769, 833, 909, 1000,
            1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000,
            2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000,
            3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000]
# Ermitteln der Schrittweite
def ie_schrittweite(ie_ist, ie_soll):
    x = ie_array.index(ie_ist)
    y = ie_array.index(ie_soll)
    return x-y
Diese Funktion wird jedesmal aufgerufen, wenn mein Istwert nicht mit dem Sollwert übereinstimmt, also komme ich nicht um ein Funktion herum.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

x und y sind schlechte Namen für Indices. Die werden üblicherweise mit Kommazahlen verbunden. m und n wären treffender, hier aber ausschreiben ist_index, soll_index.
ie_array ist immer noch eine Liste und kein Array und sollte auch ein Parameter der Funktion sein. Benutze keine globalen Variablen.

Code: Alles auswählen

ie_values = [250 ,
            256, 263, 270, 278, 286, 294, 303, 313, 323, 333,
            345, 357, 370, 385, 400, 417, 435, 455, 476, 500,
            526, 556, 588, 625, 667, 714, 769, 833, 909, 1000,
            1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000,
            2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000,
            3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000]

# Ermitteln der Schrittweite
def ie_schrittweite(ie_values, ie_ist, ie_soll):
    ist_index = ie_values.index(ie_ist)
    soll_index = ie_values.index(ie_soll)
    return ist_index - soll_index
Bei streng wachsenden Werten könnte auch bisect interessant sein:

Code: Alles auswählen

from bisect import bisect_left
def ie_schrittweite(ie_values, ie_ist, ie_soll):
    ist_index = bisect_left(ie_values, ie_ist)
    soll_index = bisect_left(ie_values, ie_soll)
    return ist_index - soll_index
Wenn alles den Präfix ie_ hat, dann ist er nicht sehr aussagekräftig und kann auch weggelassen werden:

Code: Alles auswählen

from bisect import bisect_left
def ie_schrittweite(values, ist, soll):
    ist_index = bisect_left(values, ist)
    soll_index = bisect_left(values, soll)
    return ist_index - soll_index
Zuletzt geändert von Sirius3 am Dienstag 9. Februar 2021, 10:32, insgesamt 2-mal geändert.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

@DeaD_EyE

Mit List comprehension und enumerate gibt es da auch eine Möglichkeit ohne die index() Methode. Also auch für den Fall das der gleiche Wert mehrmals vorkommt.

Code: Alles auswählen

def get_indices_from_item_in_list(list_to_search_in, item_to_search_for):
    return [index for index, element in enumerate(list_to_search_in) if element == item_to_search_for]
mochtend

@Sirius3

Ja hier muss ich zugeben, dass x und y an dieser Stelle nicht wirklich aussagekräftig sind worum es sich dort letztlich handelt.
Deine Aussage, dass x und y mit Kommazahlen und m und n eher mit ganzen Zahlen in Verbindung gebracht werden ist doch relativ nice to know vielen dank für diese kleine Erklärung.
Werde mich bei Zeiten mal in den bisect einlesen.
mochtend

Habe noch eine kleine Offtopic-Frage zu diesem Thema.
Es geht mir hier ja Hauptsächlich um die Ermittlung der Schrittweite, also die Distanz zwischen den Werten in meiner Liste.

Mit dem was hier bis jetzt gepostet wurde habe ich also meine Distanz zwischen dem Istwert und Sollwert für meinen Parameter ie erhalten.

Jetzt habe ich noch einen anderen Parameter, dessen Schrittweite verändert sich allerdings im Verlauf seines Bereichs.

Minimaler Wert = 300
Maximaler Wert = 1600
Schrittweite von 300 bis 1000 = 10
Schrittweite von 1000 bis 1600 = 50

Habe es wie folgt versucht zu realisieren:

Code: Alles auswählen

def anpassung_schrittweite(para_array, diff, para_ist, para_soll):
    if (para_array == 10) and int(new_data_soll[1] == 1):
        if para_ist < 1000:
            diff //= 10
            return diff
        elif para_ist >= 1000:
            diff //= 50
            return diff
Also wenn mein ist Parameter kleiner 1000 ist, soll die Schrittweite 10 sein, wenn der Parameter größer 1000 ist soll die Schrittweite 50 sein.

para_array ist mein Parameter an der stelle "10" aus der liste worin alle meine möglichen Parameter stehen.
diff ist die Differenz zwischen Ist- und Sollwert.

Nehmen wir an mein Sollwert hat den Wert 1200 und mein Istwert hat den Wert 600.
Die Differenz beträgt dann 600 und mein para_ist ist folglich kleiner als 1000, nun wird meine diff = 600 durch 10 geteilt, ich erhalte also -> 60.

Ich bekomme also aus der Funktion dann diese 60 zurück und eine Schleife zählt dann um 60 Schritte hoch.
Mir ist dann klar, dass ich dann völlig Überschwinge und letztlich bei 1600 lande.
Beim nächsten Durchlauf wird dann der neue Istwert abgefragt und mit meinem eigentlichen Sollwert verglichen.
Dieser ermittelt dann dass mein para_ist ja größer als 1000 ist und die Differenz zwischen meinem para_ist = 1600 und dem para_soll = 1200 beträgt dann ja 400.
Diese wird dann durch 50 geteilt und ich erhalte 8 Schritte, welche dann auf den Wert 1200 kommen.

Soweit mein Gedankengang bei der kleinen if-Anweisung dort oben...
Nur leider wird meine diff nie durch 50 geteilt.. d.h. wenn ich bei 1600 bin wird wieder durch 10 geteilt und ich erhalte eine Differenz von 40...

Hat da jemand eine Idee warum mein Programm nicht in die zweite elif Anweisung springt?



Der Post wurde jetzt irgendwie länger als gedacht, kann auch gerne einen neuen Post für dieses Topic aufmachen falls das hier dann zu lang wird.


Grüße
mochtend

Okay kurzer Edit:

Ich war blind...
Hab es jetzt einfach auch mit dem .index befehl und einer liste gemacht..
Manchmal sieht man wirklich den Wald vor lauter Bäumen nicht...

Vielen Dank nochmal an euch
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Zu Deinem Code:

Code: Alles auswählen

def anpassung_schrittweite(para_array, diff, para_ist, para_soll):
    if (para_array == 10) and int(new_data_soll[1] == 1):
        if para_ist < 1000:
            diff //= 10
            return diff
        elif para_ist >= 1000:
            diff //= 50
            return diff
Dass jetzt eine Variable mit Postfix _arrray eine einfache Zahl ist, ist noch verwirrender, als Listen array zu nennen.
Ich weiß nicht, wie oft ich es noch schreiben soll, dass Variablennamen für das Verständnis essentiell sind und falsche Namen die Frage offen lassen, ob jetzt der Code falsch ist, oder der Name.
Ein Bool in ein int umzuwanden, um es dann wieder in einem if implizit in ein Bool zu verwandeln, ist mehr als irritierend.
Wenn die elif-Bedingung das exakte Gegenteil von der if-Bedingung ist, dann benutzt man else.
Was soll denn passieren, wenn die erste if-Abfrage nicht erfüllt ist. Da fehlt Code?
new_data_soll und diff sind nirgends definiert, dafür werden para_ist und para_soll übergeben, aber nicht benutzt.
mochtend

@Sirius3

Nur um hier diese Differenz mit Liste und Array zu erklären: https://cscircles.cemc.uwaterloo.ca/13-de/
Auf dieser Seite werden Listen z.B. auch Arrays genannt, deswegen beschreibe ich meine Listen auch mit Array.

ja der int(new_data_soll) könnte besser benannt sein... allerdings steht der da noch zu test zwecken.
Mit dem else gebe ich dir recht.

Was nach der if passieren soll wenn diese nicht erfüllt ist:
Danach werden noch andere Parameter abgefragt, bei der die erste if-Anweisung dann erfüllt sein könnte.

Natürlich ist das dort oben nicht mein kompletter Code und ich bezweifle auch, dass wenn ich hier 1500 Zeilen reinposte mehr Übersicht ins spiel kommt, als wenn ich hier einen schnipsel rausnehme.
Dieser Schnipsel ist bis auf die Parameter, welche mit reingegeben werden auch völlig Unabhängig vom vorherigen oder weiterem Verlauf des beiläufigen Codes.

para_soll und para_ist werden halt zum beispiel bei dem Schnipsel mit dem ie welches oben steht gebraucht.
Ich bin mir auch darüber im klaren, dass ich mich nicht exakt an diese pythonic norm halte, das liegt aber auch daran, dass ich auch erst ein paar Monate Erfahrung mit Python habe.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Du solltest keine Seiten nennen, die Deiner Argumentation widersprechen. Da ganz Fett bei dem Ausrufezeichen steht:
Was Python eine Liste nennt, würde in den meisten anderen Programmiersprachen als Array bezeichnet werden. Python hat außerdem etwas anderes und wesentlich fortgeschritteneres, das es als Array bezeichnet.
Also, in Python sind Arrays etwas anderes als Listen und Du solltest Listen nicht Arrays nennen. Generell sollte der Datentyp nicht im Variablennamen auftauchen, weil der sich auch mal nachträglich noch ändert und dann müßte man viele Stellen im Programm anpassen.
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

@mochtend: Das ist anscheinend ein klassischer Fall von „Es steht im Internet, also muss es auch stimmen.“.

Das, was in Python `list` heißt, wird in C++ `std::vector` genannt. In Rust `Vec`. In Java `ArrayList`. In C# `List`. In all diesen Sprachen gibt es auch etwas, das „Array“ genannt wird, das ist aber etwas fundamental anderes als `list`.

In Javascript und PHP gibt es etwas, das `Array` (bzw. `array`) heißt. Das ist allerdings auch etwas komplett anderes als `list` in Python und eher mit einem `dict` zu vergleichen, das nur integrale Schlüssel hat.

Worauf ich hinaus will: Terminologie ist wichtig, wenn du effizient mit anderen Menschen kommunizieren willst. In verschiedenen Sprachen heißen verschiedene Dinge gleich und gleiche Dinge unterschiedlich. Deswegen muss man sich auf die Terminologie der jeweiligen Sprache einlassen, um Verwirrung zu vermeiden.

Klassisches Beispiel: Wenn du mit etwas zu spät fertig wirst und deine Erklärung dazu auf Englisch “I was hardly working.” ist, wirst du auch komisch angeguckt. Genauso, wenn du eine Liste in Python Array nennst.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1020
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

narpfel hat geschrieben: Dienstag 9. Februar 2021, 15:23 “I was hardly working.” ist, wirst du auch komisch angeguckt.
Den muss ich mir merken :lol:

Ähnlich sehe ich das mit der allgemeingültigen Bezeichnung Variablen.
Selbst in der Dokumentation von Python ist die Rede von Variablen an vielen Stellen, aber es sind keine oder doch?

Alles Namen mit einer Referenz auf Objekte.

Was passiert, wenn man auf einen Namen zugreift, der nicht existiert? -> NameError
Bei Klassen ist es dann ein AttributeError. Klassen haben Methoden und Attribute.

Ich habe aber noch nie einen VariableError gesehen (gibt es nicht).

Wieso ist dann immer die Rede von Variablen.
Das ist wahrscheinlich wie mit dem Schraubenzieher. Fachkräfte nennen es Schraubendreher.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DeaD_EyE: Zu einer Variable gehört ein Name, ein Wert, ein Typ, und ein Ort wo der Wert gespeichert ist. Das hat Python alles. Und wenn Du „Variable“ in einer Fehlermeldung sehen möchtest, kein Problem:

Code: Alles auswählen

In [113]: f()                                                                   
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-113-c43e34e6d405> in <module>
----> 1 f()

<ipython-input-112-559a327f4cd1> in f()
----> 1 def f(): x += 1

UnboundLocalError: local variable 'x' referenced before assignment
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

@__blackjack__: Und wenn sich der Ort ändert? Ist das dann eine neue Variable? Der GC in PyPy schiebt ja gerne mal Werte im Speicher hin und her.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@narpfel: Nö, warum sollte das eine neue Variable sein? Der Ort gehört in Python zum Wert, also alleine Zuweisung eines anderen Wertes bedeutet ja auch schon, dass sich der Ort ändert. Wert und damit Typ und Ort können auch undefiniert sein. Siehe `UnboundLocalError`. Der Laufzeitumgebung ist bekannt, dass es eine lokale Variable gibt, aber die hat zu dem Zeitpunkt keinen Wert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten