Quelqu'un ici a-t-il un code utile qui utilise la fonction reduction () en python? Existe-t-il un code autre que les + et * habituels que nous voyons dans les exemples?
Reportez-vous à Fate of Reduce () en Python 3000 par GvR
Quelqu'un ici a-t-il un code utile qui utilise la fonction reduction () en python? Existe-t-il un code autre que les + et * habituels que nous voyons dans les exemples?
Reportez-vous à Fate of Reduce () en Python 3000 par GvR
from functools import reduce
permet au même code de fonctionner sur Python 2 et 3.Réponses:
Les autres utilisations que j'ai trouvées pour cela en plus de + et * étaient avec et et ou, mais maintenant nous avons
any
etall
pour remplacer ces cas.foldl
etfoldr
viennent souvent dans Scheme ...Voici quelques usages mignons:
Aplatir une liste
Objectif:
[[1, 2, 3], [4, 5], [6, 7, 8]]
devenir[1, 2, 3, 4, 5, 6, 7, 8]
.Liste des chiffres d'un nombre
Objectif:
[1, 2, 3, 4, 5, 6, 7, 8]
devenir12345678
.Voie moche et lente:
Jolie
reduce
façon:la source
timeit.repeat('int("".join(map(str, digit_list)))', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
prend environ 0,09 seconde tandis quetimeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,1000))', number=1000)
prend 0,36 seconde (environ 4 fois plus lent). Fondamentalement, la multiplication par 10 devient coûteuse lorsque la liste devient grande, tandis que int vers str et la concaténation restent bon marché.timeit.repeat('convert_digit_list_to_int(digit_list)', setup = 'digit_list = [d%10 for d in xrange(1,10)]\ndef convert_digit_list_to_int(digits):\n i = 0\n for d in digits:\n i = 10*i + d\n return i', number=100000)
prend 0,06 s,timeit.repeat('reduce(lambda a,d: 10*a+d, digit_list)', setup = 'digit_list = list(d%10 for d in xrange(1,10))', number=100000)
prend 0,12 s et la conversion des chiffres en méthode str prend 0,16 s.reduce()
peut être utilisé pour trouver le plus petit multiple commun pour 3 nombres ou plus :Exemple:
la source
lcm
dans la deuxième ligne?lcm()
renvoie le plus petit multiple commun de deux nombres.reduce()
pourrait être utilisé pour résoudre les noms en pointillés (oùeval()
est trop dangereux pour être utilisé):la source
Trouvez l'intersection de N listes données:
Retour:
via: Python - Intersection de deux listes
la source
Je pense que réduire est une commande idiote. Par conséquent:
la source
L'utilisation de ce
reduce
que j'ai trouvé dans mon code impliquait la situation où j'avais une structure de classe pour l'expression logique et j'avais besoin de convertir une liste de ces objets d'expression en une conjonction des expressions. J'avais déjà une fonctionmake_and
pour créer une conjonction à partir de deux expressions, alors j'ai écritreduce(make_and,l)
. (Je savais que la liste n'était pas vide; sinon, cela aurait été quelque chose comme çareduce(make_and,l,make_true)
.)C'est exactement la raison pour laquelle (certains) programmeurs fonctionnels aiment
reduce
(ou replient les fonctions, comme de telles fonctions, sont généralement appelées). Il y a souvent déjà de nombreuses fonctions binaires comme+
,*
,min
,max
, concaténation et, dans mon cas,make_and
etmake_or
. Avoir unreduce
rend trivial de lever ces opérations vers des listes (ou des arbres ou tout ce que vous avez, pour les fonctions de repli en général).Bien sûr, si certaines instanciations (telles que
sum
) sont souvent utilisées, vous ne voulez pas continuer à écrirereduce
. Cependant, au lieu de définir lesum
avec une boucle for, vous pouvez tout aussi facilement le définir avecreduce
.La lisibilité, comme mentionné par d'autres, est en effet un problème. Vous pourriez cependant faire valoir que la seule raison pour laquelle les gens trouvent
reduce
moins «clair» est que ce n'est pas une fonction que beaucoup de gens connaissent et / ou utilisent.la source
and
opérateur:L and reduce(make_and, L)
si le retour d'une liste vide est approprié dans ce casComposition des fonctions : si vous disposez déjà d'une liste de fonctions que vous souhaitez appliquer successivement, telles que:
Ensuite, vous pouvez tous les appliquer consécutivement avec:
Dans ce cas, le chaînage de méthodes peut être plus lisible. Mais parfois, ce n'est pas possible, et ce type de composition peut être plus lisible et maintenable qu'une
f1(f2(f3(f4(x))))
sorte de syntaxe.la source
Vous pouvez remplacer
value = json_obj['a']['b']['c']['d']['e']
par:Si vous avez déjà le chemin
a/b/c/..
sous forme de liste. Par exemple, modifiez les valeurs dans le dictionnaire des dictionnaires imbriqués à l'aide des éléments d'une liste .la source
@Blair Conrad: Vous pouvez également implémenter votre glob / reduction en utilisant sum, comme ceci:
C'est moins verbeux que l'un ou l'autre de vos deux exemples, est parfaitement pythonique et ne représente toujours qu'une seule ligne de code.
Donc, pour répondre à la question initiale, j'essaie personnellement d'éviter d'utiliser réduire car ce n'est jamais vraiment nécessaire et je trouve que c'est moins clair que d'autres approches. Cependant, certaines personnes s'habituent à réduire et en viennent à le préférer à la liste des compréhensions (en particulier les programmeurs Haskell). Mais si vous ne pensez pas déjà à un problème en termes de réduction, vous n'avez probablement pas à vous soucier de son utilisation.
la source
sum
etreduce
conduisent à un comportement quadratique. Il peut se faire dans le temps linéaire:files = chain.from_iterable(imap(iglob, args))
. Bien que cela n'ait probablement pas d'importance dans ce cas en raison du temps nécessaire à glob () pour accéder à un disque.reduce
peut être utilisé pour prendre en charge les recherches d'attributs chaînés:Bien sûr, cela équivaut à
mais c'est utile lorsque votre code doit accepter une liste arbitraire d'attributs.
(Les attributs chaînés de longueur arbitraire sont courants lorsqu'il s'agit de modèles Django.)
la source
reduce
est utile lorsque vous avez besoin de trouver l'union ou l'intersection d'une séquence d'set
objets semblables.(Outre les
set
s réels , un exemple de ceux-ci sont les objets Q de Django .)D'un autre côté, si vous traitez avec
bool
s, vous devez utiliserany
etall
:la source
Après avoir greffé mon code, il semble que la seule chose que j'ai utilisée pour réduire soit le calcul du factoriel:
la source
J'écris une fonction de composition pour un langage, donc je construis la fonction composée en utilisant réduire avec mon opérateur apply.
En un mot, compose prend une liste de fonctions à composer en une seule fonction. Si j'ai une opération complexe qui est appliquée par étapes, je veux tout mettre ensemble comme ceci:
De cette façon, je peux ensuite l'appliquer à une expression comme ceci:
Et je veux que ce soit équivalent à:
Maintenant, pour construire mes objets internes, je veux qu'il dise:
(La classe Lambda crée une fonction définie par l'utilisateur et Apply crée une application de fonction.)
Maintenant, réduisez, malheureusement, les plis dans le mauvais sens, alors j'ai fini par utiliser, à peu près:
Pour comprendre ce que produit la réduction, essayez-les dans le REPL:
la source
compose = lambda *func: lambda arg: reduce(lambda x, f: f(x), reversed(funcs), arg)
de générer toutes les combinaisons possibles de fonctions pour les tests de performances.réduire peut être utilisé pour obtenir la liste avec le nième élément maximum
renverrait [5, 2, 5, 7] car c'est la liste avec un maximum de 3ème élément +
la source
Réduire ne se limite pas aux opérations scalaires; il peut également être utilisé pour trier les choses dans des seaux. (C'est ce que j'utilise le plus souvent pour réduire).
Imaginez un cas dans lequel vous avez une liste d'objets et que vous souhaitez la réorganiser hiérarchiquement en fonction des propriétés stockées à plat dans l'objet. Dans l'exemple suivant, je produis une liste d'objets de métadonnées liés à des articles dans un journal encodé en XML avec la
articles
fonction.articles
génère une liste d'éléments XML, puis les mappe un par un, produisant des objets contenant des informations intéressantes à leur sujet. Sur le front-end, je vais vouloir laisser l'utilisateur parcourir les articles par section / sous-section / titre. J'utilise doncreduce
pour prendre la liste des articles et retourner un dictionnaire unique qui reflète la hiérarchie section / sous-section / article.Je donne les deux fonctions ici parce que je pense que cela montre comment la carte et la réduction peuvent bien se compléter lorsqu'il s'agit d'objets. La même chose aurait pu être accomplie avec une boucle for, ... mais passer du temps sérieux avec un langage fonctionnel a eu tendance à me faire penser en termes de map et de réduire.
Au fait, si quelqu'un a un meilleur moyen de définir des propriétés comme je le fais dans
extract
, où les parents de la propriété que vous souhaitez définir n'existent peut-être pas encore, veuillez me le faire savoir.la source
Je ne sais pas si c'est ce que vous recherchez, mais vous pouvez rechercher le code source sur Google .
Suivez le lien pour une recherche sur 'function: reduction () lang: python' sur la recherche Google Code
À première vue, les projets suivants utilisent
reduce()
etc. etc. mais alors ce ne sont guère surprenants car ce sont d'énormes projets.
La fonctionnalité de réduction peut être réalisée en utilisant la récursivité de la fonction que Guido pensait plus explicite.
Mettre à jour:
Depuis que la recherche de code de Google a été interrompue le 15 janvier 2012, en plus du retour aux recherches Google régulières, il y a quelque chose appelé Collection d'extraits de code qui semble prometteur. Un certain nombre d'autres ressources sont mentionnées dans les réponses à cette question (fermée) Remplacement de Google Code Search? .
Mise à jour 2 (29 mai 2017):
Une bonne source d'exemples Python (en code open-source) est le moteur de recherche Nullege .
la source
for
boucle.lang:python "reduce("
trouvera des définitions enreduce
fonction du style de codage du code source.la source
la source
J'avais l'habitude
reduce
de concaténer une liste de vecteurs de recherche PostgreSQL avec l'||
opérateur dans sqlalchemy-searchable:la source
J'ai une ancienne implémentation Python de pipegrep qui utilise réduire et le module glob pour créer une liste de fichiers à traiter:
Je l'ai trouvé pratique à l'époque, mais ce n'est vraiment pas nécessaire, car quelque chose de similaire est tout aussi bon, et probablement plus lisible
la source
files = [glob.glob(f) for f in args]
itertools
, en utilisant laflatten()
recette de docs.python.org/library/itertools.html , puis d'écrire:files = flatten(glob.glob(f) for f in args)
(Et cette fois, j'ai testé le code avant de le publier, et je sais que cela fonctionne correctement.)files = chain.from_iterable(imap(iglob, args))
oùchain
,imap
proviennent duitertools
module etglob.iglob
est utile si un modèle deargs
peut générer des fichiers de plusieurs répertoires.Supposons qu'il existe des données statistiques annuelles stockées dans une liste de compteurs. Nous voulons trouver les valeurs MIN / MAX de chaque mois sur les différentes années. Par exemple, pour janvier, ce serait 10. Et pour février, ce serait 15. Nous devons stocker les résultats dans un nouveau compteur.
la source
J'ai des objets représentant une sorte d'intervalles qui se chevauchent (exons génomiques), et j'ai redéfini leur intersection en utilisant
__and__
:Ensuite, quand j'en ai une collection (par exemple, dans le même gène), j'utilise
la source
Je viens de trouver une utilisation utile de
reduce
: fractionner une chaîne sans supprimer le délimiteur . Le code provient entièrement du blog Programately Speaking. Voici le code:Voici le résultat:
Notez qu'il gère les cas extrêmes que la réponse populaire dans SO ne fait pas. Pour une explication plus approfondie, je vous redirige vers l'article de blog original.
la source
Utilisation de réduire () pour savoir si une liste de dates est consécutive:
la source