9
votes

Précédance de l'opérateur Python

Les Documents Python disent que * et / ont la même précalence.
Je sais que les expressions en python sont évaluées de gauche à droite.

Puis-je compter sur cela et supposer que j * j / m est toujours égal à (j * j) / m Éviter les parenthèses?
Si tel est le cas, puis-je supposer que cela détient des opérateurs avec la même préséance en général?

PS: la question telle qu'elle va bien pour mes besoins, Je suis venu à elle tout en lisant un code entier uniquement (comme l'exemple ci-dessus) sans parenthèses, qui à l'époque me méfiait beaucoup.


4 commentaires

"Explicit est meilleur que implicite.", "Face à l'ambiguïté, refuse la tentation de deviner." - PEP 20


Britannique: Si vous lisiez un "code entier unique", vous avez un problème beaucoup plus gros: quelle version de Python était destinée à être utilisée pour l'exécuter? Le code a-t-il de __future__ division d'importation à l'avant? Devant que / soit lu comme et / ou modifié en // ?


@John Machin: / signifie une division entière dans ce cas, est Python 2.6 sans les trucs futurs, j'ai noté que les codes comme J j / m (J J) / m lorsque l'égalité était égale, mais craint-elle sur la cohérence si ce comportement.


Maintenant, je peux lire et comprendre quel code comme celui-ci signifie J m / j j / j.


3 Réponses :


14
votes

Oui - différents opérateurs ayant la même précision sont laissés-associatifs; C'est-à-dire que les deux éléments les plus grands seront utilisés, puis le résultat et le 3ème élément, et ainsi de suite.

Une exception est la ** code> opérateur: p>

>>> 2 ** 2 ** 3
256


8 commentaires

L'affectation n'est en fait pas une expression en python et = pas un opérateur dans le sens normal; La priorité de l'opérateur ne s'applique pas. L'affectation à plusieurs objectifs est explicitement définie dans la grammaire pour être exactement que: attribuer le même objet à plusieurs cibles.


Mauvais à propos de l'affectation, de la modification des pls! Le seul opérateur de Python qui est associé à droite à gauche est ** , comme dans 2 ** 3 ** 4


@Amber: (1) Comme @nas Banov a dit, ** est le seul opérateur Python qui est associatif à droite (2) qu'il est juste associatif avec lui-même est le résultat inconnu de fait [1] (3) Les opérateurs de comparaison sont non associatifs ... a signifie ni (a ni a <(b < ) --- S'il vous plaît considérer la modification ultime (supprimer votre réponse).


Pourquoi supprimer une réponse quand elle pourrait être modifiée pour être améliorée? Sans parler, vous avez suffisamment de représentant que vous auriez pu simplement la modifier vous-même.


@John: honnêtement, je ne fais pas cela pour le représentant; Même si je le faisais, je suis à peu près sûr que je frappe la casquette du Daily Rep, quelle que soit cette question. Je ne vois pas le point de supprimer ce qui est maintenant une réponse concise et correcte à la question de l'OP.


@Amber: Mais ce n'est pas correct; Vous ne répondez pas à la première question de l'OP ("Puis-je compter") et de donner une généralisation incorrecte (voir mes opérateurs de comparaison de mon commentaire) comme réponse à sa deuxième question (puis-je supposer).


Je suis sûr que "oui" est une réponse assez claire à la première question de l'OP. Les comparaisons sont une affaire de bord, mais c'est assez simple pour ajouter une note à ce sujet.


... Sauf que y n'est évalué qu'une seule fois.



3
votes

Réponse courte: Oui.

Le Documentation Python dit ce qui suit: p>

Les opérateurs dans la même boîte ont la même précalence. À moins que la syntaxe soit explicitement donnée, les opérateurs sont binaires. Les opérateurs dans le même groupe de boîtes laissé à droite (à l'exception des comparaisons, y compris des tests, qui ont tous la même préséance et la même chaîne de gauche à droite ... et l'exponentiation, qui groupes de droite à gauche). P> BlockQuote>

Ainsi, en d'autres termes, la réponse à votre question est oui, les opérateurs ayant la même précision seront regroupés à gauche à l'écart de Comparations qui chaîne forte> plutôt que le groupe : p> xxx pré>

et exponentation: p >

>>> x = 1
>>> y = x = 2
>>> y
2


4 commentaires

L'affectation n'est pas un opérateur (voir ci-dessus) et les cibles sont en fait pas évaluées à gauche. La RHS de l'affectation est évaluée, puis les cibles sont évaluées laissées à droite et attribuées à. Vous pouvez voir la distinction lorsque vous vérifiez l'ordre des fichiersCalls par exemple a (). A, b (). B = c (). C : vous verrez que c ( ) est appelé, alors l'attribut C est récupéré, puis a () est appelé et l'attribut A attribué à, et alors seulement la même chose pour b ()


Je ne voulais pas impliquer que l'assignation était un opérateur, c'est pourquoi c'est enfin. J'ai légèrement changé le libellé sur la mission.


Votre libellé implique toujours que l'ordre d'évaluation de x et y concerne le résultat attribué à y . Ce ne est pas. Les valeurs de x et y ne sont jamais impliquées dans l'affectation. y = x = 2 signifie strictement "Attribuer 2 à y et à x ", pas "Attribuer 2 à x , alors la valeur résultante de x à y "(qui encore, vous pouvez voir quand vous impliquez Des objectifs d'affectation plus complexes, tels que lors de l'utilisation de propriétés qui se sont définis sur différentes valeurs que vous les attribuez.


Ce libellé vient directement de la documentation Python: docs.python.org/reference/expressions .html # évaluation-commander



13
votes

Mais, si elle vous est ambiguë - le codeur - et cela doit être parce que vous devez demander, alors vous attendez à ce que ce soit au moins aussi ambigu pour le lecteur et gaspiller quelques octets de clarté.

S'appuyant sur La priorité est excellente si vous êtes un compilateur. p>

Réponses ajoutées aux commentaires forts>: P>

Pour le code de lecture de la personne qui rencontre une ambiguïté qui nécessite une consultation extérieure pour l'assurance, vous devriez supposer que le prochain lecteur sera Soyez moins averti que vous et les sauvegarder l'effort et l'erreur humaine évitable d'analyser la même construction et d'ajouter la parenthèse pour eux. P>

Comme cela se produit, même la réponse acceptée était incorrecte (en raison de justification, pas d'effet, voir son premier commentaire) que je n'étais pas au courant et non plus une fraction de ceux qui la précipitaient. P >

sur la déclaration sur l'algèbre de base, l'exemple particulier utilisé dans l'OP est instructif. Indépendamment de la précédente de l'opérateur, l'expression j * (j / m) code> est algébriquement identique à (j * j) / m code>. Malheureusement, l'algèbre de Python n'est qu'une approximation d'algèbre "platonique" qui pourrait générer des réponses incorrectes pour l'une ou l'autre forme en fonction des magnitudes de j code> et m code>. Par exemple: P>

>>> m = 1e306
>>> m
1e+306
>>> j = 1e307
>>> j
9.9999999999999999e+306
>>> j / m
10.0
>>> j*j
inf
>>> j * (j / m)
1e+308
>>> (j * j) / m
inf
>>> ((j * j) / m) == (j * (j/m))
False


7 commentaires

Je donnerais +10 à cette réponse si je pouvais. :) C'est un point très important.


Pour obtenir un acarien philosophique, la réponse acceptée est en effet la bonne réponse à la question posée. Ce qui doit vouloir dire que la question est fausse et c'est au point où il pose des questions sur "en évitant les parenthèses". Ayant récemment dû mener à travers une bibliothèque travailleuse et tortueuse, je suis devenu extrêmement sensible à la différence entre les normes expresses de Python et son utilisation dans la pratique courante.


Pourquoi supposez-vous que j'essaie d'écrire du code? Et si ... j'essaie de lire.


Mes deux bits valant la peine: attendre des parenthèses redondantes dans une expression impliquant uniquement des opérateurs + - * / les opérateurs sont ridicules ... La priorité et l'associativité sont (implicitement) enseignées dans des cours d'algèbre scolaire, n'est-ce pas? Considérées comme des connaissances de base pour un programmeur informatique, oui / non? D'autre part, en utilisant des parenthèses autour des ops, comme un bit-shift, un peu-et, etc., qui sont utilisées rarement et ont une priorité différente dans différentes langues devraient être obligatoires dans les normes de projet ou d'équipe.


S'il y a un doute, vous devriez toujours utiliser des parenthèses. L'OP affirme en fait qu'il n'était pas sûr de ce que la priorité s'applique, il est donc correct pas de compter sur eux dans ce cas.


@MSW: J'ai ajouté un commentaire dans la question.


@ Paddy3118: Rien à faire avec "pas sûr". L'OP dit en effet qu'il a lu les documents de Python "Python Docs disent que * et / ont la même précalence" mais doute de la fiabilité de la mise en œuvre "Puis-je compter [sur] .. .? " - une bouilloire très différente de poisson, à laquelle la réponse est "oui, en python comme dans [presque toutes les autres langues".