Je suis un novice en python qui essaie de réaliser ce qui suit:
J'ai une liste de listes:
lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]
Je veux mapper lst dans une autre liste contenant uniquement le deuxième plus petit nombre de chaque sous-liste. Le résultat devrait donc être:
[345, 465, 333]
Par exemple, si j'étais simplement intéressé par le plus petit nombre, je pourrais faire:
map(lambda x: min(x),lst)
J'aimerais pouvoir faire ceci:
map(lambda x: sort(x)[1],lst)
mais le tri ne s'enchaîne pas. (renvoie Aucun)
quelque chose comme ça n'est pas non plus autorisé:
map(lambda x: sort(x); x[1],lst) #hence the multiple statement question
Existe-t-il un moyen de faire cela avec map en python mais sans définir une fonction nommée ? (c'est facile avec des blocs anonymes en rubis, par exemple)
lambda x: sort(x) OR x[1]
fonctionnerait: Ici, le OR évalue son premier argument (valeur de retour Aucun) comme un bool (=> False), et dans ce cas OU renvoie son deuxième argument. Mais comme le disent les réponses, mieux vaut éviter lambda.Réponses:
Il y a plusieurs réponses différentes que je peux donner ici, de votre question spécifique à des préoccupations plus générales. Donc du plus spécifique au plus général:
Q. Pouvez-vous mettre plusieurs déclarations dans un lambda?
R. Non, mais vous n'avez pas vraiment besoin d'utiliser un lambda. Vous pouvez placer les instructions dans un
def
fichier. c'est à dire:Q. Pouvez-vous obtenir le deuxième élément le plus bas d'un lambda en triant la liste?
R. Oui. Comme le souligne la réponse d'Alex ,
sorted()
est une version de tri qui crée une nouvelle liste, plutôt que de trier sur place, et peut être chaînée. Notez que c'est probablement ce que vous devriez utiliser - c'est une mauvaise pratique pour votre carte d'avoir des effets secondaires sur la liste d'origine.Q. Comment dois-je obtenir le deuxième élément le plus bas de chaque liste dans une séquence de listes?
A.
sorted(l)[1]
n'est pas vraiment le meilleur moyen pour cela. Il a une complexité O (N log (N)), alors qu'une solution O (n) existe. Cela peut être trouvé dans le module heapq.Alors utilisez simplement:
Il est également généralement considéré comme plus clair d'utiliser une compréhension de liste, ce qui évite complètement le lambda:
la source
k
(comme ici avec `` deuxième plus bas '') seO(k*log(n)+n)
simplifie àO(n)
Mettre les instructions dans une liste peut simuler plusieurs instructions:
Par exemple:
la source
None
.Voyageur du temps ici. Si vous souhaitez généralement avoir plusieurs instructions dans un lambda, vous pouvez passer d'autres lambdas comme arguments à ce lambda.
Vous ne pouvez pas réellement avoir plusieurs instructions, mais vous pouvez simuler cela en passant des lambdas aux lambdas.
Edit: Le voyageur du temps revient! Vous pouvez également abuser du comportement des expressions booléennes (en gardant à l'esprit les règles de court-circuit et la véracité) pour enchaîner les opérations. L'utilisation de l'opérateur ternaire vous donne encore plus de puissance. Encore une fois, vous ne pouvez pas avoir plusieurs instructions , mais vous pouvez bien sûr avoir de nombreux appels de fonction. Cet exemple fait des choses arbitraires avec un tas de données, mais cela montre que vous pouvez faire des choses amusantes. Les instructions print sont des exemples de fonctions qui retournent
None
(tout comme la.sort()
méthode) mais elles aident également à montrer ce quelambda
fait.la source
Utilisez la fonction triée , comme ceci:
la source
[sorted(x)[1] for x in list_of_lists]
.Vous pouvez en fait avoir plusieurs instructions dans une expression lambda en python. Ce n'est pas tout à fait anodin mais dans votre exemple, les travaux suivants:
Vous devez vous assurer que chaque instruction ne renvoie rien ou si elle l'enveloppe (.. et False). Le résultat est ce qui est renvoyé par la dernière évaluation.
Exemple:
la source
Utilisation de begin () à partir d'ici: http://www.reddit.com/r/Python/comments/hms4z/ask_pyreddit_if_you_were_making_your_own/c1wycci
la source
Un moyen Hacky de combiner plusieurs instructions en une seule instruction en python consiste à utiliser le mot-clé "et" comme opérateur de court-circuit. Ensuite, vous pouvez utiliser cette instruction unique directement dans le cadre de l'expression lambda.
Ceci est similaire à l'utilisation de "&&" comme opérateur de court-circuit dans des langages shell tels que bash.
Remarquez également: vous pouvez toujours corriger une instruction de fonction pour renvoyer une valeur vraie en encapsulant la fonction.
Exemple:
Après réflexion, il est probablement préférable d'utiliser 'ou' au lieu de 'et' puisque de nombreuses fonctions renvoient '0' ou None en cas de succès. Ensuite, vous pouvez vous débarrasser de la fonction wrapper dans l'exemple ci-dessus:
'et' operera évalueront les expressions jusqu'à ce qu'il atteigne la première valeur de retour zéro. après quoi il court-circuite. 1 et 1 et 0 et 1 évaluent: 1 et 1 et 0, et supprime 1
'ou' operera évaluera les expressions jusqu'à ce qu'il atteigne la première valeur de retour différente de zéro. après quoi il court-circuite.
0 ou 0 ou 1 ou 0 évalue 0 ou 0 ou 1 et abandonne 0
la source
Ou si vous voulez éviter lambda et avoir un générateur au lieu d'une liste:
(trié (col) [1] pour col dans lst)
la source
Permettez-moi de vous présenter un hack glorieux mais terrifiant:
Vous pouvez désormais utiliser ce
LET
formulaire comme tel:qui donne:
[345, 465, 333]
la source
Vous pouvez le faire en temps O (n) en utilisant min et index au lieu d'utiliser sort ou heapq.
Créez d'abord une nouvelle liste de tout sauf la valeur minimale de la liste d'origine:
Ensuite, prenez la valeur min de la nouvelle liste:
Maintenant tous ensemble dans un seul lambda:
Oui, c'est vraiment moche, mais cela devrait être bon marché sur le plan algorithmique. Aussi, puisque certaines personnes de ce fil veulent voir les compréhensions de liste:
la source
C'est exactement ce à quoi
bind
sert la fonction d'une Monad .Avec la
bind
fonction, vous pouvez combiner plusieurs lambda en un seul lambda, chaque lambda représentant une instruction.la source
Il existe en fait un moyen d'utiliser plusieurs instructions dans lambda. Voici ma solution:
la source
exec
ne peut pas être introspectionné par un IDE intelligentOui. Vous pouvez le définir de cette façon, puis envelopper vos multiples expressions avec les éléments suivants:
Début du schéma:
begin = lambda * x: x [-1]
Progn Common Lisp:
progn = lambda * x: x [-1]
la source
Il existe de meilleures solutions sans utiliser la fonction lambda. Mais si nous voulons vraiment utiliser la fonction lambda, voici une solution générique pour gérer plusieurs instructions: map (lambda x: x [1] if (x.sort ()) else x [1], lst)
Vous ne vous souciez pas vraiment de ce que la déclaration renvoie.
la source
Oui c'est possible. Essayez ci-dessous l'extrait de code.
la source
Je vais vous donner une autre solution, faites que votre lambda appelle une fonction.
la source
junky = multiple_statements
.