Interpreting Left to right?
x=y="some string" And we know that python interprets from left to right. so why it doesnt raise a name error here saying name 'y' is not defined? another example: (1,2) + 3, here, python raises a TypeError "can only concatenate tuple(not int) to tuple" but we know (3,) is a tuple as seen by following: t=3, type(t) Arent both of this contradicting? -- Chetan H Harjani -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 2:32 PM, Chetan Harjani wrote: > x=y="some string" > And we know that python interprets from left to right. so why it doesnt > raise a name error here saying name 'y' is not defined? In most languages, the answer is that the = operator associates right to left, even though most other operators associate left to right. (That's how C does it, for instance.) But in Python, I believe it's actually one operator taking several parameters, because = is not an expression. In any case, you can safely treat = as an exception to the left-to-right rule. There are other exceptions too - note the comments in http://docs.python.org/reference/expressions.html#summary - there's not many RTL operators in Python, only those that make sense that way. :) ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On 6/24/2011 12:32 AM, Chetan Harjani wrote: x=y="some string" And we know that python interprets from left to right. Read the doc. "5.14. Evaluation order Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side." another example: (1,2) + 3, here, python raises a TypeError "can only concatenate tuple(not int) to tuple" but we know (3,) is a tuple as seen by following: But "(3,) is not what you wrote;-). The comma operator has the lowest precedence, although this is not as clear in the doc as it should be. Your expression is parsed as ((1,2)+3),. Parentheses have the highest precedence. The combination of both facts is why tuples often need to be parenthesized, as it should be here and why you added the first pair instead of writing 1,2 + 3,. Disassembly of bytecode shows how an expression was parsed. >>> from dis import dis >>> dis('(1,2)+3,') 1 0 LOAD_CONST 3 ((1, 2)) 3 LOAD_CONST 2 (3) 6 BINARY_ADD 7 BUILD_TUPLE 1 10 RETURN_VALUE -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
Terry Reedy wrote: On 6/24/2011 12:32 AM, Chetan Harjani wrote: x=y="some string" And we know that python interprets from left to right. Read the doc. "5.14. Evaluation order Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side." The example given to me when I had this question: --> x = x['huh'] = {} --> x {'huh': {...}} As you can see, the creation of the dictionary is evaluated, and bound to the name 'x'; then the key 'huh' is set to the same dictionary. If you try that the other way 'round this happens: >>> x['huh'] = x = {} Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined So -- the RHS (right hand side) gets evaluated first, then the LHSs from left to right. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 5:14 PM, Ethan Furman wrote: > --> x = x['huh'] = {} > --> x > {'huh': {...}} > I would have to call that dodgy practice... unless you have a lot of places where you need a dictionary with itself as an element, I would avoid assignments that depend on each other. Perhaps it's just because I'm a C programmer, but that code smells a lot like the classic "i = i++;" blunder - nearly as bad as land wars in Asia. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
Now its all clear. Thanks @ethan .. ur example is really scary. I didnt understand ur example fully although. See this is what i take it as: x=x['huh']={} >first python checks check that there are two = operators. >so it evaluates the RHS(since for = it is RHS to LHS) experession of right most (why is that?) >now it assigns that experrsion({...}) to x the left most as u said first RHS to LHS then LHS to RHS. >then it assigns x to to x['huh']. huh!!, ryt? may be it doesnt make sense but i guess this is the only way to actually not raise an error. Where am I wrong? On Fri, Jun 24, 2011 at 10:02 AM, Chetan Harjani wrote: > x=y="some string" > And we know that python interprets from left to right. so why it doesnt > raise a name error here saying name 'y' is not defined? > > another example: > (1,2) + 3, > here, python raises a TypeError "can only concatenate tuple(not int) to > tuple" but we know (3,) is a tuple as seen by following: > t=3, > type(t) > > Arent both of this contradicting? > > -- > Chetan H Harjani > > -- Chetan H Harjani -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 12:14:27AM -0700, Ethan Furman wrote: > The example given to me when I had this question: > > --> x = x['huh'] = {} > --> x > {'huh': {...}} > > > As you can see, the creation of the dictionary is evaluated, and > bound to the name 'x'; then the key 'huh' is set to the same > dictionary. Can you please elaborate? I really don't understand how this works at all. I would have expected a NameError from this (obviously my mental model is wrong). This single line is equivalent to: x = {} x['huh'] = x ...but I don't understand how python's evaluation semantics get from the one liner to the two liner/result at all. \t -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
Tycho Andersen wrote: On Fri, Jun 24, 2011 at 12:14:27AM -0700, Ethan Furman wrote: The example given to me when I had this question: --> x = x['huh'] = {} --> x {'huh': {...}} As you can see, the creation of the dictionary is evaluated, and bound to the name 'x'; then the key 'huh' is set to the same dictionary. Can you please elaborate? I really don't understand how this works at all. I would have expected a NameError from this (obviously my mental model is wrong). This single line is equivalent to: x = {} x['huh'] = x ...but I don't understand how python's evaluation semantics get from the one liner to the two liner/result at all. \t Think of it this way: x = x['huh'] = {} obj = {} # RHS evaluated first (and only once) x = obj# then first LHS x['huh'] = obj # then second LHS, etc ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 01:13:08PM -0700, Ethan Furman wrote: > Tycho Andersen wrote: > >On Fri, Jun 24, 2011 at 12:14:27AM -0700, Ethan Furman wrote: > >>The example given to me when I had this question: > >> > >>--> x = x['huh'] = {} > >>--> x > >>{'huh': {...}} > >> > >> > >>As you can see, the creation of the dictionary is evaluated, and > >>bound to the name 'x'; then the key 'huh' is set to the same > >>dictionary. > > > >Can you please elaborate? I really don't understand how this works at > >all. I would have expected a NameError from this (obviously my mental > >model is wrong). > > > >This single line is equivalent to: > > > >x = {} > >x['huh'] = x > > > >...but I don't understand how python's evaluation semantics get from > >the one liner to the two liner/result at all. > > > >\t > > Think of it this way: > > x = x['huh'] = {} > > obj = {} # RHS evaluated first (and only once) > > x = obj# then first LHS > > x['huh'] = obj # then second LHS, etc Yes, I understand that, but I guess I don't understand *why* things are done that way. What is the evaluation order principle at work here? I would have expected: tmp = {} x['huh'] = tmp # NameEror! That is, the right hand sides of assignments are evaluated before the left hand sides. That is (somehow?) not the case here. \t -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
In article <20110624200618.gk6...@point.cs.wisc.edu>, Tycho Andersen wrote: > Yes, I understand that, but I guess I don't understand *why* things > are done that way. What is the evaluation order principle at work > here? I would have expected: > > tmp = {} > x['huh'] = tmp # NameEror! > > That is, the right hand sides of assignments are evaluated before the > left hand sides. That is (somehow?) not the case here. http://docs.python.org/py3k/reference/simple_stmts.html#assignment-statem ents -- Ned Deily, n...@acm.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On 6/24/2011 4:06 PM, Tycho Andersen wrote: tmp = {} x['huh'] = tmp # NameEror! That is, the right hand sides of assignments are evaluated before the left hand sides. That is (somehow?) not the case here. You are parsing "a = b = c" as "a = (b = c)" which works in a language in which assignment is an expression, but does not work in Python where assignment is a statement. You have to parse it more as "(a = b) = c" but that does not work since then the first '=' is not what it seems. It is more like "(both a and b) = c". Perhaps best to expand "a = b = c" to "a = c; b = c" and see the first as an abbreviation thereof -- just delete the 'c;'. If I have ever used this sort of multiple assignment, it has been for simple unambiguous things like "a = b = 0". -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 01:24:24PM -0700, Ned Deily wrote: > In article <20110624200618.gk6...@point.cs.wisc.edu>, > Tycho Andersen wrote: > > Yes, I understand that, but I guess I don't understand *why* things > > are done that way. What is the evaluation order principle at work > > here? I would have expected: > > > > tmp = {} > > x['huh'] = tmp # NameEror! > > > > That is, the right hand sides of assignments are evaluated before the > > left hand sides. That is (somehow?) not the case here. > > http://docs.python.org/py3k/reference/simple_stmts.html#assignment-statements Perhaps I'm thick, but (the first thing I did was read the docs and) I still don't get it. From the docs: "An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right." For a single target, it evaluates the RHS and assigns the result to the LHS. Thus x = x['foo'] = {} first evaluates x['foo'] = {} which should raise a NameError, since x doesn't exist yet. Where am I going wrong? Thanks, \t -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Fri, Jun 24, 2011 at 05:02:00PM -0400, Terry Reedy wrote: > On 6/24/2011 4:06 PM, Tycho Andersen wrote: > > >tmp = {} > >x['huh'] = tmp # NameEror! > > > >That is, the right hand sides of assignments are evaluated before the > >left hand sides. That is (somehow?) not the case here. > > You are parsing "a = b = c" as "a = (b = c)" which works in a > language in which assignment is an expression, but does not work in > Python where assignment is a statement. You have to parse it more as > "(a = b) = c" but that does not work since then the first '=' is not > what it seems. It is more like "(both a and b) = c". Perhaps best to > expand "a = b = c" to "a = c; b = c" and see the first as an > abbreviation thereof -- just delete the 'c;'. > > If I have ever used this sort of multiple assignment, it has been > for simple unambiguous things like "a = b = 0". Ah, the point about the grammar is what I was missing. Thanks a bunch! \t -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
In article <20110624210835.gl6...@point.cs.wisc.edu>, Tycho Andersen wrote: > On Fri, Jun 24, 2011 at 01:24:24PM -0700, Ned Deily wrote: > > In article <20110624200618.gk6...@point.cs.wisc.edu>, > > Tycho Andersen wrote: > > > Yes, I understand that, but I guess I don't understand *why* things > > > are done that way. What is the evaluation order principle at work > > > here? I would have expected: > > > > > > tmp = {} > > > x['huh'] = tmp # NameEror! > > > > > > That is, the right hand sides of assignments are evaluated before the > > > left hand sides. That is (somehow?) not the case here. > > > > http://docs.python.org/py3k/reference/simple_stmts.html#assignment-statement > > s > > Perhaps I'm thick, but (the first thing I did was read the docs and) I > still don't get it. From the docs: > > "An assignment statement evaluates the expression list (remember that > this can be a single expression or a comma-separated list, the latter > yielding a tuple) and assigns the single resulting object to each of > the target lists, from left to right." > > For a single target, it evaluates the RHS and assigns the result to > the LHS. Thus > > x = x['foo'] = {} > > first evaluates > > x['foo'] = {} > > which should raise a NameError, since x doesn't exist yet. Where am I > going wrong? "An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right." Also, remember that in Python the "=" is not part of an expression. It's a token in the assignment statement. -- Ned Deily, n...@acm.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On Sat, Jun 25, 2011 at 7:02 AM, Terry Reedy wrote: > If I have ever used this sort of multiple assignment, it has been for simple > unambiguous things like "a = b = 0". For which it's extremely useful. Initialize a whole bunch of variables to zero... or to a couple of values: minfoo=minbar=minquux=1000 maxfoo=maxbar=maxquux=0 There are times when I miss the "assignment is an expression" concept, but I'd say this syntax covers 90% or more of use cases for assignment expressions. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
Tycho Andersen writes: > On Fri, Jun 24, 2011 at 01:24:24PM -0700, Ned Deily wrote: > > http://docs.python.org/py3k/reference/simple_stmts.html#assignment-statements > > Perhaps I'm thick, but (the first thing I did was read the docs and) I > still don't get it. From the docs: > > "An assignment statement evaluates the expression list (remember that > this can be a single expression or a comma-separated list, the latter > yielding a tuple) and assigns the single resulting object to each of > the target lists, from left to right." Notice that, in the grammar given there, there is exactly one “expression list”, following *all* of the ‘=’s. The “target lists” are each to the left of an ‘=’. > For a single target, it evaluates the RHS and assigns the result to > the LHS. Thus > > x = x['foo'] = {} > > first evaluates > > x['foo'] = {} No, that's not an “expression list” by the grammar given in the docs. The expression list consists, in your example, of “{}” only. The target lists are “x”, then “x['foo']”, in that order. -- \ “If consumers even know there's a DRM, what it is, and how it | `\ works, we've already failed.” —Peter Lee, Disney corporation, | _o__) 2005 | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
On 6/24/2011 5:08 PM, Tycho Andersen wrote: "An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right." This is the 'other' type of 'multiple assignment' a,b,c = 1,2,3 Order matters here too. a,a[1] = [1,2],3 a # [1,3] # but a[1], a = 3, [1,2] will either fail or modify what a was previously bound to before rebinding a to [1,2]. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Interpreting Left to right?
(Re: x = x['huh'] = {} which binds x to a new dictionary, then binds that dictionary's 'huh' key to the same dictionary...) In article Tycho Andersen wrote: >Perhaps I'm thick, but (the first thing I did was read the docs and) I >still don't get it. From the docs: > >"An assignment statement evaluates the expression list (remember that >this can be a single expression or a comma-separated list, the latter >yielding a tuple) and assigns the single resulting object to each of >the target lists, from left to right." The "target list" in this case is, in effect: evail("x"), eval("x['huh']") >For a single target, it evaluates the RHS and assigns the result to >the LHS. Thus > >x = x['foo'] = {} > >first evaluates > >x['foo'] = {} > >which should raise a NameError, since x doesn't exist yet. Where am I >going wrong? I believe you are still reading this as: x = (something) and setting aside "x" and "something", and only then peering into the "something" and finding: x['foo'] = {} and -- while keeping all of the other "x = (something)" at bay, trying to do the x['foo'] assignment. This is the wrong way to read it! The correct way to read it is: - Pseudo_eval("x") and pseudo_eval("x['foo']") are both to be set to something, so before we look any more closely at the "x" and "x['foo']" part, we need to evaluate the "something" part. - The "something" part is: {}, so create a dictionary. There is no name bound to this result, but for discussion let's bind "tmp" to it. - Now that we have evaluated the RHS of the assignment statement (which we are calling "tmp" even though it has no actual name), *now* we can go eval() (sort of -- we only "evaluate" them for assignment, rather than for current value) the pieces of the LHS. - The first piece of the LHS is "x". Eval-ing x for assignment gets us the as-yet-unbound "x", and we do: x = tmp which binds x to the new dictionary. - The second piece of the LHS is "x['foo']". Eval-ing this for assignment gets us the newly-bound x, naming the dictionary; the key 'foo', a string; and now we bind x['foo'], doing: x['foo'] = tmp which makes the dictionary contain itself. Again, Python's assignment statement (not expression) has the form: and the evaluation order is, in effect and using pseudo-Python: 1. -- the (single) RHS tmp = eval() 2. for in : # left-to-right = tmp When there is only one item in the (i.e., just one "x =" part in the whole statement), or when all of the parts of the target-list are independent of each other and of the , the order does not matter. When the parts are interdependent, then this left-to-right order *is* important. -- In-Real-Life: Chris Torek, Wind River Systems Intel require I note that my opinions are not those of WRS or Intel Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: gmail (figure it out) http://web.torek.net/torek/index.html -- http://mail.python.org/mailman/listinfo/python-list