Das ist ziemlich n00bish, aber ich versuche, funktionale Programmierung in Python zu lernen / zu verstehen. Der folgende Code:
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]
def maptest(foo, bar):
print foo, bar
map(maptest, foos, bars)
produziert:
1.0 1
2.0 2
3.0 3
4.0 None
5.0 None
Frage: Gibt es eine Möglichkeit, Map oder andere funktionale Tools in Python zu verwenden, um Folgendes ohne Schleifen usw. zu erzeugen?
1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]
Nur als Randnotiz, wie würde sich die Implementierung ändern, wenn es eine Abhängigkeit zwischen foo und bar gibt. z.B
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]
und drucken:
1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...
PS: Ich weiß, wie man es naiv mit if, Schleifen und / oder Generatoren macht, aber ich möchte lernen, wie man dasselbe mit funktionalen Werkzeugen erreicht. Geht es nur darum, eine if-Anweisung zu maptest hinzuzufügen oder eine andere Filterzuordnung auf Balken innerhalb von maptest anzuwenden?
python
dictionary
functional-programming
eusoubrasileiro
quelle
quelle
Antworten:
Der einfachste Weg wäre, nicht
bars
die verschiedenen Funktionen zu durchlaufen, sondern direkt darauf zuzugreifen vonmaptest
:Mit Ihrer ursprünglichen
maptest
Funktion können Sie auch eine Lambda-Funktion verwenden inmap
:quelle
Kennen Sie andere funktionale Sprachen? Versuchen Sie also zu lernen, wie Python funktionale Programmierung ausführt, oder versuchen Sie, etwas über funktionale Programmierung und die Verwendung von Python als Vehikel zu lernen?
Verstehst du auch das Listenverständnis?
ist direkt äquivalent (*) zu:
Tatsächlich war ich der Meinung
map()
, dass das Entfernen aus Python 3.0 einmal als redundant geplant war (das ist nicht geschehen).ist meistens gleichbedeutend mit:
(Es gibt einen Unterschied in der Behandlung des Falls, in dem die Sequenzen unterschiedlich lang sind. Wie Sie gesehen haben, wird
map()
None ausgefüllt, wenn eine der Sequenzen abgelaufen ist, währendzip()
angehalten wird, wenn die kürzeste Sequenz stoppt.)Um Ihre spezifische Frage zu beantworten, versuchen Sie, das Ergebnis zu erzielen:
Sie können dies tun, indem Sie eine Funktion schreiben, die ein einzelnes Argument verwendet und es druckt, gefolgt von Balken:
Alternativ können Sie eine Liste erstellen, die folgendermaßen aussieht:
und verwenden Sie Ihren Original-Maptest:
Eine Möglichkeit, dies zu tun, besteht darin, die Liste im Voraus explizit zu erstellen:
Alternativ können Sie das
itertools
Modul einziehen.itertools
enthält viele clevere Funktionen, mit denen Sie in Python eine funktionale Lazy-Evaluation-Programmierung durchführen können. In diesem Fall möchten wir, dassitertools.repeat
das Argument unbegrenzt ausgegeben wird, wenn Sie darüber iterieren. Diese letzte Tatsache bedeutet, dass wenn Sie Folgendes tun:Sie erhalten eine endlose Ausgabe, da
map()
so lange weitergearbeitet wird, wie eines der Argumente noch eine Ausgabe erzeugt. Istitertools.imap
jedoch genau wiemap()
, stoppt aber, sobald die kürzeste iterierbare Stopps.Hoffe das hilft :-)
(*) In Python 3.0 ist das etwas anders. Dort gibt map () im Wesentlichen einen Generatorausdruck zurück.
quelle
itertools.imap(f, sequence1, sequence2)
wirklich gleichbedeutend ist mit[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]
?list(itertools.imap(f, sequence1, sequence2))
Hier ist die Lösung, nach der Sie suchen:
Ich würde empfehlen, ein Listenverständnis (den
[(x, bars) for x in foos]
Teil) gegenüber der Verwendung von map zu verwenden, da dies den Aufwand eines Funktionsaufrufs bei jeder Iteration vermeidet (was sehr bedeutsam sein kann). Wenn Sie es nur in einer for-Schleife verwenden, erhalten Sie bessere Geschwindigkeiten, wenn Sie ein Generatorverständnis verwenden:Der Unterschied besteht darin, dass das Generatorverständnis träge geladen ist .
UPDATE Als Antwort auf diesen Kommentar:
Ich nehme an, das ist ein gültiger Punkt. Hierfür gibt es zwei Lösungen, an die ich denken kann. Das effizienteste ist wahrscheinlich so etwas:
Da Tupel unveränderlich sind, wird verhindert, dass Balken durch die Ergebnisse dieses Listenverständnisses (oder des Generatorverständnisses, wenn Sie diesen Weg gehen) geändert werden. Wenn Sie wirklich jedes einzelne Ergebnis ändern müssen, können Sie dies tun:
Dies kann jedoch sowohl in Bezug auf die Speichernutzung als auch in Bezug auf die Geschwindigkeit etwas teuer sein. Daher würde ich davon abraten, es sei denn, Sie müssen wirklich zu jedem von ihnen etwas hinzufügen.
quelle
Bei der funktionalen Programmierung geht es darum, nebenwirkungsfreien Code zu erstellen.
map ist eine funktionale Listentransformationsabstraktion. Sie verwenden es, um eine Sequenz von etwas zu nehmen und es in eine Sequenz von etwas anderem zu verwandeln.
Sie versuchen, es als Iterator zu verwenden. Tu das nicht. :) :)
Hier ist ein Beispiel, wie Sie mithilfe der Karte die gewünschte Liste erstellen können. Es gibt kürzere Lösungen (ich würde nur Verständnis verwenden), aber dies hilft Ihnen zu verstehen, was Map ein bisschen besser macht:
Beachten Sie an dieser Stelle, dass Sie nur eine Datenmanipulation durchgeführt haben. Jetzt können Sie es ausdrucken:
- Ich bin mir nicht sicher, was Sie unter "ohne Schleifen" verstehen. Bei fp geht es nicht darum, Schleifen zu vermeiden (Sie können nicht jedes Element in einer Liste untersuchen, ohne jedes zu besuchen). Es geht darum, Nebenwirkungen zu vermeiden und so weniger Fehler zu schreiben.
quelle
quelle
quelle
Hier ist eine Übersicht über die Parameter der
map(function, *sequences)
Funktion:function
ist der Name Ihrer Funktion.sequences
ist eine beliebige Anzahl von Sequenzen, bei denen es sich normalerweise um Listen oder Tupel handelt.map
wird sie gleichzeitig durchlaufen und die aktuellen Werte an gebenfunction
. Aus diesem Grund sollte die Anzahl der Sequenzen der Anzahl der Parameter Ihrer Funktion entsprechen.Es hört sich so an, als würden Sie versuchen, einige
function
Parameter zu iterieren , andere jedoch konstant zu halten, und dies wird leidermap
nicht unterstützt. Ich habe einen alten Vorschlag gefunden , Python eine solche Funktion hinzuzufügen, aber das Kartenkonstrukt ist so sauber und gut etabliert, dass ich bezweifle, dass so etwas jemals implementiert wird.Verwenden Sie eine Problemumgehung wie globale Variablen oder Listenverständnisse, wie andere vorgeschlagen haben.
quelle
Würde das das tun?
quelle
bar
impliziert, dass er einen iterierten Wert erhält, wenn Sie tatsächlich die gesamte Liste möchten.Wie wäre es damit:
quelle