Interpreting Left to right?

2011-06-23 Thread Chetan Harjani
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?

2011-06-23 Thread Chris Angelico
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?

2011-06-23 Thread Terry Reedy

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?

2011-06-24 Thread Ethan Furman

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?

2011-06-24 Thread Chris Angelico
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?

2011-06-24 Thread Chetan Harjani
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?

2011-06-24 Thread Tycho Andersen
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?

2011-06-24 Thread Ethan Furman

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?

2011-06-24 Thread Tycho Andersen
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?

2011-06-24 Thread Ned Deily
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?

2011-06-24 Thread Terry Reedy

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?

2011-06-24 Thread Tycho Andersen
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?

2011-06-24 Thread Tycho Andersen
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?

2011-06-24 Thread Ned Deily
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?

2011-06-24 Thread Chris Angelico
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?

2011-06-24 Thread Ben Finney
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?

2011-06-24 Thread Terry Reedy

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?

2011-06-25 Thread Chris Torek
(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