2010-10-01 3 views
4

Si j'ai une valeur et une liste de termes supplémentaires que je veux multiplièrent la valeur:Est-ce que cette fonction doit utiliser reduce() ou existe-t-il une façon plus pythonique?

n = 10 
terms = [1,2,3,4] 

Est-il possible d'utiliser une compréhension de la liste pour faire quelque chose comme ceci:

n *= (term for term in terms) #not working... 

Or est le seul moyen:

n *= reduce(lambda x,y: x*y, terms) 

Ceci est sur Python 2.6.2. Merci!

+1

Voir aussi [? Quel module Python est adapté pour la manipulation de données dans une liste] (http://stackoverflow.com/questions/595374/whats-the-python-function -comme-somme-mais-pour-multiplication) – outis

Répondre

7

Réduire n'est pas le seul moyen. Vous pouvez également écrire comme une simple boucle:

for term in terms: 
    n *= term 

Je pense que cela est beaucoup plus clair que l'utilisation reduce, surtout quand on considère que beaucoup de programmeurs Python ont jamais vu reduce et le nom ne contribue guère à transmettre aux gens qui voir pour la première fois ce qu'il fait réellement.

Pythonic ne signifie pas écrire tout comme compréhensions ou toujours utiliser un style fonctionnel si possible. Python est un langage multi-paradigme et écrire du code impératif simple quand c'est approprié est Pythonic.

Guido van Rossum ne veut pas non plus reduce en Python:

donc réduire maintenant(). C'est en fait celui que j'ai toujours détesté le plus, car, à part quelques exemples impliquant + ou *, presque chaque fois que je vois un appel reduce() avec un argument de fonction non-trivial, je dois saisir le stylo et le papier diagramme ce qui est réellement alimenté dans cette fonction avant que je comprenne ce que le réduire() est censé faire. Donc, dans mon esprit, l'applicabilité de reduce() est plutôt limitée aux opérateurs associatifs, et dans tous les autres cas, il est préférable d'écrire explicitement la boucle d'accumulation.

Il n'y a pas beaucoup d'opérateurs associatifs. (Ce sont des opérateurs X pour lesquels (a X b) X c est égal à X (b X c).) Je pense que c'est à peu près limité à +, *, &, |, ^, et raccourci et/ou. Nous avons déjà sum(); J'échangerais heureusement reduce() pour le produit(), donc cela prend soin des deux utilisations les plus courantes. [...]

En Python 3, réduire a été déplacé vers le module functools.

+0

Mes pensées exactement, juste une minute plus vite! – JoshD

+0

Je pensais que "pythonic" signifiait "écrire tout en une ligne" – Falmarri

+3

Hmm, il a ajouté 'any()' et 'all()' (qu'il a proposé dans le paragraphe suivant après cette citation), mais n'a jamais ajouté 'product () '. Indépendamment du sort ultime de «réduire» (et je n'ai jamais eu de difficulté à le lire), 'n * = product (terms)' est assez clair. Je pense que décider entre une boucle ou un appel de réduction ou autre est moins important que de le mettre dans une fonction bien nommée. – Ken

8

reduce est la meilleure façon de faire cette IMO, mais vous n'avez pas besoin d'utiliser un lambda; à la place, vous pouvez utiliser l'opérateur * directement:

import operator 
n *= reduce(operator.mul, terms) 

n est maintenant Voir les docs 240. pour la operator module pour plus d'informations.

2

Encore une autre façon:

import operator 
n = reduce(operator.mul, terms, n) 
Questions connexes