Funktionswerte in Variablen speichern

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

Ich habe folgendes Problem. Ich kann mir die Werte der Funktion interval(x, partition) printen lassen, allerdings möchte ich die Werte in einer Variblen speichern.
Beispielsweise ist das mein Output: 2 1 11 5 3 0 9 3 3 11
Diesen Output hätte ich wie im Code angegeben gerne in iamstupid = find_interval(x, I) speichern.
Das funktioniert leider nicht. Kann da jemand weiterhelfen?

times_to_repeat = 0

while times_to_repeat >= 0:
r = uniform.rvs(size=10)

def find_interval(x, partition):
""" find_interval -> i
partition is a sequence of numerical values
x is a numerical value
The return value "i" will be the index for which applies
partition < x < partition[i+1], if such an index exists.
-1 otherwise
"""

for i in range(0, len(partition)):
if x < partition:
return i-1
return -1
I = [0, 0.08, 0.15, 0.24, 0.36, 0.40, 0.48, 0.56, 0.64, 0.72, 0.80, 0.88, 1.0]
for x in [r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9]]:
print(find_interval(x, I), end=" ")
#iamstupid = find_interval(x, I)
times_to_repeat -= 1
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Weißt Du was Listen sind und wie man sie erzeugen kann? Wenn nicht, ließ das Kapitel zu Listen nochmal in dem Tutorial durch, das Du zum Python-Lernen benutzt.

Zum Code: eine while-Schleife, die exakt einmal durchlaufen wird, ist unnötig. Funktionsdefinitionen sollten am Anfang der Datei stehen, nicht in Schleifen. Es wäre gut gewesen, zu verraten, woher `uniform` kommt. Die Funktion `find_interval` funktioniert nicht. Warum erzeugst Du für die for-Schleife eine Liste aus Einzelelementen eines Arrays? Du kannst direkt über `r` iterieren.
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

Ich weiß, wie ich Listen erzeugen kann, aber da hat das Tutorial nicht weitergeholfen für das Problem.
Die while-Schleife wird nur zur Vereinfachung einmal durchlaufen, damit es für den Moment übersichtlich bleibt.
'uniform' kommt von 'from scipy.stats import uniform'. So sollte der Code funktionieren.

Über r iterieren wär wohl geschickter, aber bringt mich nicht näher an die Lösung.

Hast du eine Idee, wie ich konkret den Output hier in einer Variable speichern kann?

Vielen Dank!
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Welche Methoden hat denn eine Liste? Und welche davon könnte man benutzen, um Elemente in eine Liste einzutragen?
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

Ich würde eine leere Liste erzeugen und es dann mit extend probieren, allerdings ist mir unklar was ich als Argument dann verwenden muss. Also:
list= [ ]
list.entend(???)
find_interval(x, I) als Argument funktioniert jedenfalls nicht...
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

List.extend braucht auch eine Liste als Argument, das ist das Problem. Deswegen ist das wohl der falsche Ansatz
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

dann nimm doch append.
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

append benötigt aber genau so eine Liste als Argument...
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@schuesra: Nein. Was wäre denn dann Deiner Meinung nach der Unterschied zwischen `append()` und `extend()`?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

bei append:
x = [1, 2, 3]
x.append([4, 5])
print (x)
-> [1, 2, 3, [4, 5]]
bei extend:
x.extend([4,5])
print(x)
->[1, 2, 3, 4, 5]
Also wird bei append das komplette Objekt angehängt und nicht die einzelnen Elemente...

Wenn ich es aber mit append versuche, bekomme ich folgende Fehlermeldung:
"TypeError: descriptor 'append' requires a 'list' object but received a 'int'"

Hier die entsprechende Änderung:
I = [0, 0.08, 0.15, 0.24, 0.36, 0.40, 0.48, 0.56, 0.64, 0.72, 0.80, 0.88, 1.0]
for x in [r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9]]:
print(find_interval(x, I), end=" ")
l=[]
list.append(find_interval(x, I))
times_to_repeat -= 1
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@schuesra: An welche Liste versuchst Du denn da etwas anzuhängen? Was ist `list`?

Eine unnötige ``while``-Schleife trägt sicher nicht zur Übersichtlichkeit bei, sondern macht das Programm nur unnötig komplexer. Nebenbei ist auch das ``while`` an sich nicht das richtige wenn man weiss wie oft eine Schleife durchlaufen werden soll — da nimmt man eine ``for``-Schleife für.

Schleifen über ``range(len(sequence))`` sind in Python ein „anti pattern“ wenn die Laufvariable im Schleifenkörper für Indexzugriffe verwendet wird. Man kann direkt über die Elemente iterieren. Und falls man zusätzlich eine laufende Zahl benötigt, gibt es die `enumerate()`-Funktion.

Hier mal Dein Code etwas aufgeräumter:

Code: Alles auswählen

#!/usr/bin/env python3
from scipy.stats import uniform


def find_interval(x, partition):
    """ find_interval -> i
    partition is a sequence of numerical values
    x is a numerical value
    The return value "i" will be the index for which applies
    partition[i] < x < partition[i+1], if such an index exists.
    -1 otherwise
    """
    for index, value in enumerate(partition):
        if x < value:
            return index - 1
    return -1


def main():
    values = [
        0, 0.08, 0.15, 0.24, 0.36, 0.40, 0.48, 0.56, 0.64, 0.72, 0.80, 0.88, 1.0
    ]
    for x in uniform.rvs(size=10):
        print(find_interval(x, values), end=' ')
        #iamstupid = find_interval(x, values)
    print()


if __name__ == '__main__':
    main()
Du möchtest Dir vielleicht auch die „list comprehension“-Syntax anschauen. Und für ein etwas effizienteres `find_interval()` eventuell das `bisect`-Modul.

Mit -1 als Zahl mit besonderer Bedeutung wäre ich übrigens vorsichtig, insbesondere wenn es sich ansonsten um Indexwerte handelt. Der Wert -1 ist in Python ein legaler Indexwert. Da kann es schnell mal passieren, dass man mit so einer Liste mit Indizes weiterarbeitet und vergisst auf eine enthaltene -1 zu prüfen und dann rechnet das Programm möglicherweise falsch, ohne das man das merkt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
schuesra
User
Beiträge: 26
Registriert: Donnerstag 4. Oktober 2018, 17:40

Ich meine natürlich l.append(find_interval(x, I))

Ich möchte an die leere Liste l die jeweiligen Intervalle anhängen. Also insgesamt 10 Elemente.
Vielen Dank für die aufgeräumtere Version, ich werde ich bisschen Zeit zum Verstehen benötigen.

Du meinst das mir list comprehension helfen könnte für die Lösung des Problems, oder war das ein allgemeiner Tipp?

Wenn nicht, wie kann ich vorgehen um auf die Lösung zu kommen?
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@schuesra: Eine „list comprehension“ kann helfen das Problem zu lösen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo hast Du denn jetzt noch mit ` l.append(find_interval(x, I))` ein Problem? , außer dass das kleine l nicht vom großen I zu unterscheiden ist.

Und List comprehension löst kein Problem, solange man noch nicht verstanden hat, wie einfache Listen funktionieren.
Antworten