This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: different behaviour with for loop... interpreted vs scripted
Type: behavior Stage:
Components: Versions: Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eric.smith, ezio.melotti, jacobidiego
Priority: normal Keywords:

Created on 2010-07-13 00:11 by jacobidiego, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (3)
msg110150 - (view) Author: Diego Jacobi (jacobidiego) Date: 2010-07-13 00:11
Hi.
I am not a python expert and i was trying to reduce this next code:

        data = []
        i = 0
        for j in range(packetlen+1):
            print i, self.channels_in[ channels[i] ]
            data.append( self.channels_in[ channels[i] ].pop() )
            i += 1
            if i >= len(channels):
                i=0

into something like this:

        data = []
        for j in range(packetlen+1), i in channels:
            print j, i
            data.append( self.channels_in[ i ].pop() )

which is much more readable and short.
But i didnt know if this sintax is really supported (also i didnt found examples on internet), so i just tried.

I runned the script and it didnt complains with errors, BUT i found that the behavior is not what i expected.

I expected j to take value of range() and i to take the values of channels until range() gets empty.

well, the actual behavior is that j takes the value of the complete range() as in
j = range(..)

and the for loop iterates as in 
for i in channels:


ALSO i tested this un the python command line and it produces different behaviours:

the same sintax writen as:

for j in range(1,5), i in range(120,500,12):
   print j, i

produces 

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined


Thats all. I guess that if it produces different results, then there is an error happening here.


If there is a pythonic way to do this:
for j in range(packetlen+1), i in channels:

please tell me.

Cheers.
Diego
msg110160 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2010-07-13 08:25
"for j in range(1,5), i in range(120,500,12):"
is equivalent to
"for j in (range(1,5), i in range(120,500,12)):"
so the sequence here is a tuple that contains range(1,5) as first element and "i in range(120,500,12)" as second element.
Since 'i' is needed before the loop starts to check if it's in range(120,500,12), if you don't define it, it raises a NameError.
If 'i' already had some value before, then the code works, but it doesn't do what you expect. I.e., this code:
>>> i = 0
>>> for j in (range(1,5), i in range(120,500,12)):
...   j,i
...

results in :
(range(1, 5), 0)
(False, 0)

because the first element of the sequence is range(1,5) so at the first iteration j = range(1,5) and since 'i' is untouched it's still 0, so the first line ends up being (range(1,5), 0).
At the second iteration the value of j is "i in range(120,500,12)" and since 'i' is 0 and 0 is not in range(120,500,12), that evaluates to False. So we have j = False and 'i' is still 0, hence the (False, 0) in the second line.

The different results are because probably you had 'i = <something>' in your program but not in the interpreter.

What you want is "for j, i in zip(range(packetlen+1), channels): ..." or possibly "for j, i in enumerate(channels): ...".

I'm not sure anything can be done in this case, except maybe require () in case the sequence contains an 'in', but I'm not sure it's worth doing it. 
I'll leave this open for a while to see if other developers have any comment.
msg110164 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-07-13 09:13
Excellent explanation. It's just a misunderstanding of how the language works, so nothing to do here. Closing.
History
Date User Action Args
2022-04-11 14:57:03adminsetgithub: 53486
2010-07-13 09:13:38eric.smithsetstatus: pending -> closed

nosy: + eric.smith
messages: + msg110164

resolution: not a bug
2010-07-13 08:26:00ezio.melottisetstatus: open -> pending
nosy: + ezio.melotti
messages: + msg110160

2010-07-13 00:11:11jacobidiegocreate