7
votes

Fonction pour appeler une fonction à plusieurs reprises?

Considérez la fonction hypothétique répétercall , qui prend comme arguments A NO-args appelable FUNC et un entier positif N et renvoie une liste dont les membres sont obtenus en exécutant func () n fois. Il soutient un flux infini de hijinks stupides comme: xxx

je pourrais jurer que j'ai vu une fonction comme répétercall quelque part dans les bibliothèques standard Python 2.x, Mais je ne peux pas le trouver. Si je ne rêvais pas ça, où dans la bibliothèque standard puis-je le trouver?

PS: Je sais que c'est trivial de rouler son propre, mais je déteste Les roues réinventer, en particulier celles-ci sont déjà dans la bibliothèque standard. Je suis pas demandant comment rouler le mien.

EDIT: Fabriqué encore plus explicite que je ne demande pas comment coder répéterCall .


1 commentaires

N'est-ce pas simplement la cartographie sur une plage?


5 Réponses :


3
votes

Voulez-vous dire quelque chose comme ça?: XXX

semble assez succinct non?


1 commentaires

«Je sais que c'est trivial de rouler le sien, mais je déteste réinventer des roues» - cela ne répond pas à la question.



2
votes

Vous pouvez utiliser Appliquer Fonction intégrée à cet effet < Pré> xxx

note ** Du manuel L'utilisation de Apply () est équivalente à la fonction (* args, ** Mots-clés).

donc répétercall peut également être écrit comme xxx


6 commentaires

appliquer a été obsolète depuis Python2.3. Vous pouvez simplement appeler la fonction avec son * args et ** kwargs


La fonction peut être appelée directement, même si son nom est transmis sous forme d'argument: DEF RepeatCall (FUNC, N): RETOUR [FUNC () POUR I DANS LA GAMME (0, N)]


Oui Appliquer est complètement inutile ici et partout ailleurs.


Cela ne répond pas à la question - «Je sais que c'est trivial de rouler le sien, mais je déteste réinventer des roues». Il ne voulait pas de mise en œuvre.


@AgF: La post-scriptuma a été ajoutée 15 minutes après la question initiale :-)


Non, ce n'était pas. Regardez le Modifier l'historique ; C'est dans la version originale, tout simplement pas audacieux.



14
votes

Vous avez vu cela dans la bibliothèque standard, pas la bibliothèque standard elle-même.

C'est répéterfunc à partir du iTERTools recettes : xxx

Il permet des arguments et devrait (théoriquement) fonctionner mieux qu'une liste Compréhension car Func doit seulement être recherché une fois. répéter est également plus rapide que plage pour quand vous n'utilisez pas le compteur.


9 commentaires

Techniquement, le vôtre n'est pas la réponse exacte non plus, à moins que vous ne dissiez que cela n'existe pas dans la STDLIB. Je ne pense pas une recette utilisant itheroTools.starmap est différente de la rouleau. Bien que je suppose que je montrais cela, vous êtes dans une ronde de manière à dire que vous devez vous lancer.


@JDI Oui, je reste que cela n'existe pas dans la bibliothèque standard. Il se souvient de le voir parce que c'est dans les docs. C'est la réponse à sa question.


Ensuite, je suppose que 90% de ce que vous avez écrit n'est pas nécessaire s'il n'est pas intéressé à voir des implémentations du code. Donc vraiment, que 90% sont comme les autres.


@JDI que 90% sont inclus tout simplement pour que les gens ne doivent pas avoir à cliquer sur le iTertools docs pour voir de quoi je parle. Les réponses sont donc censées se tenir seul autant que possible et ne dépendent pas des ressources externes.


OK, alors disons que 30% ne sont pas nécessaires, car l'explication à la fin était en givrage :-)


@JDI Oui, c'est vraiment un commentaire sur ma propre réponse plutôt que de la réponse elle-même :)


Je suppose que le retour doit être enveloppé dans la liste () pour renvoyer une liste avec les résultats suivants?


@MR_AND_MRS_D Si vous souhaitez réellement une liste avec tous les résultats, assurez-vous - l'un des grands avantages d'itoTools est que vous pouvez obtenir une seule chose à la fois si vous n'en avez pas besoin tout à la fois.


@Mr_and_mrs_d Oui, si vous appelez la fonction A Nombre de fois, et que vous êtes OK avec l'attente jusqu'à la dernière instance Dernière de la fonction pour la finition avant de voir le premier . Mais si vous voulez itérer sur les sorties de fonction telles qu'elles se produisent (par exemple, si vous utilisez Epoll : pour fn, ev in (Evénement pour les événements dans RepeatFunc (e.Poll) pour l'événement en événements): ), alors la liberté de consommer le générateur que comme si nécessaire peut être une dépose.



4
votes

Il y a une raison pour laquelle cela n'existe pas: la manière idiomatique de coder une fonction qui ne prend pas d'arguments sur chaque appel et renvoie quelque chose de nouveau consiste à le coder comme générateur.

Vous utiliseriez ensuite une compréhension de la liste ou une expression génératrice pour l'appeler autant de fois que vous le souhaitez: [suivant (gen) pour i in xrange (5)] . Mieux encore, Gen peut être le résultat d'une expression de générateur comme (ID (dict (dict ()) pour i in (itoTools.repeat (aucun))) .

Ainsi, Python n'a pas de support de bibliothèque pour cela, car il le supporte de manière syntaxique.


9 commentaires

Vous avez raison, c'est plus "pythonique" que la solution dans les recettes iTertools . Mais, comme tous les autres, ce n'est pas une réponse à la question. Il demandait où il avait vu une implémentation, pas comment le faire. Cela aurait été un bon commentaire.


@Agf pas vraiment. Cela nécessite au moins deux paragraphes, et il explique pourquoi il n'y a pas de solution de la forme que Pos demande.


Sa question n'est pas "Est-ce dans la bibliothèque standard", c'est "" je l'ai déjà vu auparavant; je pense que c'était dans la bibliothèque standard mais je ne peux pas le trouver. Où est-ce? " Un commentaire correspond à 500 caractères; Votre message a de la place à épargner et sans blocs formatés que vous ne pouviez pas afficher dans un commentaire.


@Agf Si vous sentez cela fortement, signalez-le. Pourquoi es-tu si en colère contre tout le monde qui a posté une réponse?


Il n'y a pas de "colère" dedans. Quand une réponse ne répond pas à la question, c'est le bruit. Quand j'ai commis une erreur et affiché quelque chose qui n'est pas sur le point, je le supprime et je l'apprécie quand d'autres soulignent mes erreurs. Sauf si une réponse contient aucune information Je ne le signale pas; La décision de la supprimer ou non est l'affiche, voir ma question méta sur le sujet . Et je ne baisse pas que l'intention était de fournir des informations utiles et que l'information n'est pas fausse.


Clairement, vous avez de la colère, car vous venez de descendre ma réponse (correcte). Je viens de voir Cette réponse et commentaire - Je suis surpris que vous descendiez une réponse correcte après un désaccord, car ce commentaire le rend clairement clair que vous pensez que ce n'est pas difficile.


@AgF J'ai bownvoted votre réponse parce que vous vous êtes plaint de chaque autre réponse sur des motifs fragiles. Ce n'est pas cool.


Qu'en est-il de pour A pour la boucle, cependant? Je cherche la même réponse, et si la génératrice ou les compréhensions de liste sont bonnes, pour n in (func () pour i in gamme (10)) semble un peu gênant


@LUCRETIL Je ne suis pas sûr de ce que vous voulez dire. Il n'y a aucune raison pour que vous ayez une expression de boucle et de générateur dans votre exemple. Il suffit d'écrire: pour i in gamme (10): FUNC () ou si vous souhaitez avoir un appareil propres à passer ailleurs, utilisez (Func () pour i in gamme (10)) .



0
votes

Tout en lisant des commentaires ici, j'ai réalisé que iter (foo, expr) créera un itérateur infini du résultat de FOO tant qu'il n'est jamais égal à EXPR .

Pour l'exemple de la question, iter (lambda: id (dict (dict ()), aucun) créera un itérateur infini d'ID de dicts.

Bien que ce ne soit pas une réponse directe à cette question, je l'ai trouvé utile depuis dans mon usecase, je voulais que cela fait partie d'une expression finie zip de toute façon et il suffit d'avoir besoin de l'itérateur pour continuer à produire des éléments producteurs. < / p>

Espérons que cela pourrait aider les autres qui tombent sur cette question


0 commentaires