Funktionsliste an Funktion übergeben

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
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Hallo, stehe auf dem Schlauch und weiß nicht einmal, ob der Betreff das Problem trifft. Deshalb beschreibe ich einfach, was ich machen möchte.
Ich habe n Funktionen und ich habe z.B. 2 np-arrays einer größeren Dimension. Mit einer "for-Schleife" berechne ich irgendwas über den Arrays.
"for a, b in zip(a1, a2): ...Berechnungen..."
nun möchte ich innerhalb der Schleifen aus der Liste der Funktionen jeweils eine Abarbeiten. func sei die Liste der Funktionen f1, f2...
Ich möchte also "for a, b, f in zip(a1, a2, func): ...a + (b * f(y))..." wobei y ein Parameter der Funktion ist, der seinerseits aus a, b berechnet wird.
Als Lösung ist mir bisher nur eingefallen, einen Index in den zip-Schleifen zu verwenden, der dann über eine if-Abfrage die entsprechende Funktion ausführt. Das scheint mir aber schwer "Un-pythisch" (bin Anfänger und komme von Visual-Basic...), trotzdem fällt mir aber keine bessere Lösung ein. Vielleicht kann jemand etwas erhellendes zu meinem Problem sagen. Danke!
Und ich arbeite mit Spider3 und Python 3.6
Gruß Rainer
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bist du sicher, dass das zip auch über die f gehen soll? Wenn nicht, schachtele doch einfach die Schleifen:

Code: Alles auswählen

for f in funcs:
      for ... # deine Schleife
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Ja, natürlich! Wenn ich Schachtle, dann kommt es einer If-Abfrage gleich. Ich möchte aber der Schleife eine Funktion übergeben. Vielleicht habe ich das Problem nicht ausreichend beschrieben!?
GRuß Rainer
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Verstehe ich nicht. Nirgendwo ist eine if-Abfrage hier. Wieso kommt das dem dann gleich? Und einer Schleife kannst du nichts übergeben. Die iteriert über etwas. Kannst du vielleicht ein kleines minimales Beispiel ohne numpy aber einfach mit zwei Listen a und b und den Funktionen machen, welches das illustriert was da wie berechnet werden soll?
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

pyzip hat geschrieben: Dienstag 22. Mai 2018, 21:45 Vielleicht habe ich das Problem nicht ausreichend beschrieben!?
Ich befürchte, so ist es. Fangen wir noch mal an:
pyzip hat geschrieben: Dienstag 22. Mai 2018, 17:51 Ich habe n Funktionen und ich habe z.B. 2 np-arrays einer größeren Dimension. Mit einer "for-Schleife" berechne ich irgendwas über den Arrays.
"for a, b in zip(a1, a2): ...Berechnungen..."
Welche Namen sind was? Sind a1 und a2 die np-arrays? Und jetzt soll mit denen paarweise etwas berechnet werden. Was passiert mit dem Berechnungsergebnis? Wird es "weggeworfen", oder irgendwo aufgehoben, oder spielt für Berechnungen im nächsten Schleifendurchlauf eine Rolle? Was heißt "einer größeren Dimension" - es handelt sich um eindimensionale np-arrays, die mehr als n Elemente haben?
pyzip hat geschrieben: Dienstag 22. Mai 2018, 17:51 nun möchte ich innerhalb der Schleifen aus der Liste der Funktionen jeweils eine Abarbeiten.
Innerhalb der Schleifen jeweils eine: Ist gemeint, dass bei jedem Schleifendurchlauf jeweils die nächste aus der Liste genommen werden soll? Was heißt abarbeiten - hat das was mit dem "irgendwas berechnen" von oben zu tun? Was passiert mit den restlichen Elementen von a1 und a2?
pyzip hat geschrieben: Dienstag 22. Mai 2018, 17:51 func sei die Liste der Funktionen f1, f2...
Ich möchte also "for a, b, f in zip(a1, a2, func): ...a + (b * f(y))..." wobei y ein Parameter der Funktion ist, der seinerseits aus a, b berechnet wird.
Und warum machst du es nicht, wenn du es möchtest? Irgendwie vermisse ich dein Problem...
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Hallo, ich habe mich wahrscheinlich nicht ausreichend genau ausgedrückt. Ich will in jedem Durchlauf die entsprechende Funtion anwenden. In IF geht es, aber ich will Py, wie gesagt!!
Gruß Rainer
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das trägt leider nicht zur Klärung bei. Schreib es doch mit dem if auf, wenn das deine Lösung ist. Dann können wir eine pythonischere vorschlagen. Aber bisher versteht hier keiner, was dein Problem eigentlich ist.
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Also warum mache ich es nicht?!
List[f1, f2, f3] sind 3 Funktrionen, die ich definiert habe. func = List[f1, f2, f3]
"for a, b, f in zip(a1, a2, func): ...a + (b * f(y))..." wobei y ein Parameter der Funktion ist, der seinerseits aus a, b berechnet wird.
Es geht nicht. Warum oder was frage ich falsch??
Gruß Rainer
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

pyzip hat geschrieben: Dienstag 22. Mai 2018, 23:07 Es geht nicht. Warum oder was frage ich falsch??
Du beantwortet Fragen nicht. Du schreibst keinen vollständigen Code auf, der "nicht geht". Du schreibst nicht, was "es geht nicht" bedeutet.

Nach dem was du schreibst, müsste nämlich alles gehen:

Code: Alles auswählen

In [18]: func = [min, max]

In [19]: a1 = [1, 2, 3]

In [20]: a2 = [5, 6, 7, 8]

In [21]: for a, b, f in zip(a1, a2, func):
    ...:     print(f(a, b))
    ...:     
1
6
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

CODE: ALLES AUSWÄHLEN

In [17]: func = [print, max]

In [18]: func = [min, max]

In [19]: a1 = [1, 2, 3]

In [20]: a2 = [5, 6, 7, 8]

In [21]: for a, b, f in zip(a1, a2, func):
...: print(f(a, b))
...:
1
6

Hallo, habe gerade noch reingesehen...die Antwort trifft meine Frage nicht, weil func eine Liste von Funktionen ist! Und in "a, b" werden Berechnungen über Werte und Parameter der Funktion gemacht. In jeder Schleife soll eine andere(die nächste) Funktion mit dem aktuellen Partameter ausgeführt werden. Ich weiss, dass das theoretisch wahnsinnig ausschaut, aber in Echt sollte es ohne "If" funktionieren!
Morgen setze ich einen Code rein, der es verdeutlicht! Danke und gute Nacht!
Rainer
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Hallo, ich habe mal aufgeschrieben, wie ich das mit den If-Abfragen meine und dahinter, was nicht geht.
In Zeile 53 bekomme ich die Fehlermeldung: "x = f(y), TypeError: 'list' object is not callable"
Die Frage ist also wohl, wie ich die Listenobjekte aufrufbar mache. Habe aber keine Idee! Und sorry, dass mal wieder die Zeilennummern fehlen...
Gruß Rainer

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed May 23 14:33:29 2018

@author: Rainer
"""

import numpy as np

def f1(y):
    r = y**2
    return r

def f2(y):
    r = y*2
    return r

def f3(y):
    r = y*3
    return r

def main():
    
    a1 = np.array([[1,2,3],[2,3,4],[2,2,2]])
    a2 = np.array([[1,2,3],[2,3,4],[2,2,2]])
    
    i = 0
    for a, b in zip(a1, a2):
        y = sum(a + b)
        print(y)
        if i == 0:
            x = f1(y)
            print(i, x)
        if i == 1:
            x = f2(y)
            print(i, x)
        if i == 2:
            x = f3(y)
            print(i, x)
#        x = funcs[i](y)
        
        i += 1
        
    # was ich gern hätte:
        
    funcs = [[f1], [f2], [f3]]
#    funcs = np.array(funcs)
    print(funcs)
    print(type(funcs))
    for a, b, f in zip(a1, a2, funcs):
        y = sum(a + b)
        x = f(y)
        print(x)
        
if __name__ == '__main__':
    main()
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Nein, Listenobjekte macht man nicht aufrufbar. Aber zumindest rein syntaktisch ist Dein jetziges Problem klar. Du speicherst in func eben drei Listen, obgleich Du vermutlich statt dessen direkt die Funktionsobjekte dort ablegen möchtest. Du hast bei Deinen Datenstrukturen schlicht die Übersicht verloren.
pyzip
User
Beiträge: 89
Registriert: Freitag 16. Juni 2017, 19:36

Hallo, super! Ich dachte ja schon, dass ich den Wald vor lauter Bäumen nicht sehe :oops:
Mit "funcs = [f1, f2, f3]" geht es einfach.
Danke und Gruß, Rainer
Antworten