0
votes

Carte ou appliquer une fonction à une seule valeur - la bonne façon de faire à Python 3

Dans mon projet Python, im beaucoup d'endroits apparaît la fonctionnalité équivalente à: xxx

mais je suis sûr qu'il doit y avoir une fonction intégrée de Python (3?) pour cette tâche triviale , je ne veux pas inventer un bixier et utiliser cette merde dans le projet. Tout le monde connaît la fonction de construction appropriée pour cela?


6 commentaires

Les gens demandent généralement comment faire des choses comme ça. La chose droite est de rendre l'appelant responsable de l'enveloppement d'un seul élément dans une liste, plutôt que d'essayer d'accueillir des entrées de deux types complètement différents.


Et si: - Vous ne voulez pas créer une liste s'il n'y a qu'un seul élément là-bas, juste pour la performance? - Ou vous avez une sorte de structure d'arbres / graphiques, où les feuilles sont des non-listes et des succursales sont des listes?


La création d'une liste singleton ne sera pas significativement plus chère que le type de reniflement que vous avez déjà. Python n'a rien de tel que la classe de type Foncteur de HASKELLL, ce qui vous permet de mapper une valeur de manière préservée à la structure.


Je suppose que j'ai besoin de fournir l'exemple pourquoi c'est nécessaire, moment ...


Donc, si vous avez une carte dans laquelle les valeurs peuvent être des listes ou non, faites-en simplement des listes simples?


Juste pour l'argument direct sur la fonction. Considérons mapper (F, [1, 2, [3, 4], 5]) . Il n'y a pas de mapper . Tout ce qu'il fait, c'est s'appliquer f à chaque élément du démonteur. C'est jusqu'à F pour savoir comment gérer chaque type de type STI .


4 Réponses :


3
votes

N'essayez pas d'écrire cela du tout. Au lieu de

mapper(f, [1,2,3,4])
mapper(f, [1])  # Not mapper(f, 1)
mapper(f, some_tree_object.depth_first_iterator())
mapper(f, some_tree_object.breadth_first_iterator())


8 commentaires

non, idefinity a une structure imbriquée où l'article peut être une liste ou non


Si c'est imbriqué, l'itérateur détruit cette structure. Tout ce que vous obtenez est un flux linéaire d'éléments de celui-ci.


Non, ce sera la profondeur d'abord la recherche (et fonctionnera) alors


Cela est entièrement traité par l'itérateur pour éléments ; mapper ne s'en souciera pas à ce sujet.


mapper est assez trivial. C'est si trivial, en fait, qu'il y a peu de raisons de le définir. C'est juste une combinaison de mappe et partielle : mapper (f, itr, * args) == carte (partielle (F, * args), ITR) < / Code>, et comme toute utilisation de carte uniquement pour les effets secondaires, vous préférez écrire un explicite pour en boucle.


Gah, prenez mon dernier commentaire avec un grain de sel. partiel (f, * args) (k) fait k la dernier argument de position sur f , pas le premier . Tant que mapper ne crée pas une liste de résultats jetable, il ne doit pas être confondu avec la carte de la carte :)


Est-ce un moyen de définir la position d'un argument en partiel?


Seulement si vous utilisez des arguments de mots clés; Les arguments de position sont remplis strictement de gauche à droite.



0
votes

Je suis à peu près sûr qu'il n'y a pas d'encadré à one-liner pour cela. J'ai cette fonction d'assistance dans mon projet; xxx pré>

L'objectif de cette fonction est de convertir toute entrée en une liste code>. Si un seul élément est donné, il renvoie une liste de cet élément. P>

Je l'utilise dans d'autres fonctions, P>

def map_or_single(container, func, *args):
    container = any2list(container)
    for k in container:
        func(k, *args)


1 commentaires

Basiclyi ferait:



1
votes

Ceci est un clair AntiPattern , donc il n'y a donc pas de «bon» ou «correct». Pour ce faire en python (ou la plupart, sinon toutes les autres langues). Vous pouvez certainement proposer une grande variété de solutions fragiles, mais c'est le type de chose qui conduit à des bogues à long terme pour très peu d'avantages.

Ce problème est résolu en évitant complètement ce modèle et en nécessitant une entrée de l'utilisateur. Pour être conforme à un motif au lieu de deux ou plus. p>

au lieu de cette interface: p> xxx pré>

Vous avez cette interface: p>

func(single)
map(func, iterable)


2 commentaires

Ceci est fondamentalement pas différent de ma réponse.


Bien que je fournisse un exemple d'entrées simples d'emballage, ce n'est pas le point principal que je rentre chez moi avec ma réponse. J'aurais pu répertorié une poignée d'autres exemples de différentes manières de contourner ce problème, mais que ce type de motif doit être évité pour une qualité à long terme et remplacé essentiellement de tout autre. L'opérateur Splat, enveloppant des entrées simples dans une liste, écrivant deux fonctions distinctes pour une seule ou une valeur multiple, l'utilisation de la carte intégrée, etc. Toutes lesquelles cela peut être accompli.



0
votes

Vous pouvez utiliser des fonctions mapper () et partielle () : xxx


0 commentaires