C'est assez n00bish, mais j'essaie d'apprendre / comprendre la programmation fonctionnelle en python. Le code suivant:
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)
produit:
1.0 1
2.0 2
3.0 3
4.0 None
5.0 None
Y a-t-il un moyen d'utiliser map ou tout autre outil fonctionnel en python pour produire ce qui suit sans boucles, etc.
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]
Juste comme note latérale, comment l'implémentation changerait s'il y avait une dépendance entre foo et bar. par exemple
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]
et imprimez:
1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...
PS: Je sais comment le faire naïvement en utilisant des if, des boucles et / ou des générateurs, mais j'aimerais apprendre comment réaliser la même chose en utilisant des outils fonctionnels. S'agit-il simplement d'ajouter une instruction if à maptest ou d'appliquer une autre carte de filtre aux barres en interne dans maptest?
python
dictionary
functional-programming
eusoubrasileiro
la source
la source
Réponses:
Le moyen le plus simple serait de ne pas passer
bars
par les différentes fonctions, mais d'y accéder directement depuismaptest
:Avec votre
maptest
fonction d' origine , vous pouvez également utiliser une fonction lambda dansmap
:la source
Connaissez-vous d'autres langages fonctionnels? c'est-à-dire essayez-vous d'apprendre comment python fait de la programmation fonctionnelle, ou essayez-vous d'apprendre la programmation fonctionnelle et l'utilisation de python comme véhicule?
Aussi, comprenez-vous les compréhensions de listes?
est directement équivalent (*) à:
En fait, je pense
map()
que la suppression de python 3.0 était autrefois redondante (cela ne s'est pas produit).équivaut principalement à:
(il y a une différence dans la façon dont il gère le cas où les séquences sont de longueur différente. Comme vous l'avez vu,
map()
remplit None lorsque l'une des séquences s'épuise, alors quezip()
s'arrête lorsque la séquence la plus courte s'arrête)Donc, pour répondre à votre question spécifique, vous essayez de produire le résultat:
Vous pouvez le faire en écrivant une fonction qui prend un seul argument et l'affiche, suivi de barres:
Vous pouvez également créer une liste qui ressemble à ceci:
et utilisez votre maptest d'origine:
Une façon de faire serait de construire explicitement la liste au préalable:
Vous pouvez également insérer le
itertools
module.itertools
contient de nombreuses fonctions intelligentes qui vous aident à faire de la programmation d'évaluation paresseuse de style fonctionnel en python. Dans ce cas, nous voulonsitertools.repeat
, qui affichera son argument indéfiniment au fur et à mesure que vous l'itérerez. Ce dernier fait signifie que si vous faites:vous obtiendrez une sortie sans fin, car
map()
continue tant que l'un des arguments produit encore une sortie. Cependant,itertools.imap
c'est juste commemap()
, mais s'arrête dès que l'itérable le plus court s'arrête.J'espère que cela t'aides :-)
(*) C'est un peu différent en python 3.0. Là, map () renvoie essentiellement une expression de générateur.
la source
itertools.imap(f, sequence1, sequence2)
est vraiment équivalent à[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]
?list(itertools.imap(f, sequence1, sequence2))
Voici la solution que vous recherchez:
Je recommanderais d'utiliser une compréhension de liste (la
[(x, bars) for x in foos]
partie) plutôt que d'utiliser la carte car cela évite la surcharge d'un appel de fonction à chaque itération (ce qui peut être très important). Si vous allez simplement l'utiliser dans une boucle for, vous obtiendrez de meilleures vitesses en utilisant une compréhension du générateur:La différence est que la compréhension du générateur est chargée paresseusement .
MISE À JOUR En réponse à ce commentaire:
Je suppose que c'est un point valable. Il y a deux solutions à cela auxquelles je peux penser. Le plus efficace est probablement quelque chose comme ceci:
Puisque les tuples sont immuables, cela empêchera les barres d'être modifiées par les résultats de cette compréhension de liste (ou la compréhension du générateur si vous suivez cette voie). Si vous avez vraiment besoin de modifier chacun des résultats, vous pouvez le faire:
Cependant, cela peut être un peu cher à la fois en termes d'utilisation de la mémoire et de vitesse, je vous le déconseille donc, à moins que vous n'ayez vraiment besoin d'ajouter à chacun d'eux.
la source
La programmation fonctionnelle consiste à créer du code sans effets secondaires.
map est une abstraction de transformation de liste fonctionnelle. Vous l'utilisez pour prendre une séquence de quelque chose et la transformer en une séquence de quelque chose d'autre.
Vous essayez de l'utiliser comme itérateur. Ne fais pas ça. :)
Voici un exemple de la façon dont vous pouvez utiliser map pour créer la liste souhaitée. Il existe des solutions plus courtes (j'utiliserais simplement des compréhensions), mais cela vous aidera à comprendre ce que la carte fait un peu mieux:
Remarquez à ce stade, vous n'avez effectué qu'une manipulation de données. Vous pouvez maintenant l'imprimer:
- Je ne suis pas sûr de ce que vous entendez par «sans boucles». fp ne consiste pas à éviter les boucles (vous ne pouvez pas examiner tous les éléments d'une liste sans les visiter). Il s'agit d'éviter les effets secondaires, donc d'écrire moins de bogues.
la source
la source
la source
Voici un aperçu des paramètres de la
map(function, *sequences)
fonction:function
est le nom de votre fonction.sequences
est un nombre quelconque de séquences, qui sont généralement des listes ou des tuples.map
va les parcourir simultanément et donner les valeurs actuelles àfunction
. C'est pourquoi le nombre de séquences doit être égal au nombre de paramètres de votre fonction.On dirait que vous essayez d'itérer pour certains
function
paramètres de, mais que vous gardez les autres constants, et malheureusementmap
ne supporte pas cela. J'ai trouvé une vieille proposition pour ajouter une telle fonctionnalité à Python, mais la construction de la carte est si propre et bien établie que je doute que quelque chose comme ça soit jamais implémenté.Utilisez une solution de contournement telle que des variables globales ou des compréhensions de liste, comme d'autres l'ont suggéré.
la source
Est-ce que cela le ferait?
la source
bar
implique qu'il reçoit une valeur itérée, alors que vous voulez réellement la liste entière.Que dis-tu de ça:
la source