Python Iterables struggling using map() built-in

Terry Reedy tjreedy at udel.edu
Tue Dec 9 15:06:51 EST 2014


On 12/9/2014 12:03 AM, Terry Reedy wrote:
>> Roy Smith wrote:
>>
>>> Chris Angelico wrote:
>
>>>> def myzip(*args):
>>>>      iters = map(iter, args)
>>>>      while iters:
>>>>          res = [next(i) for i in iters]
>>>>          yield tuple(res)
>>>
>>> Ugh.  When I see "while foo", my brain says, "OK, you're about to see a
>>> loop which is controlled by the value of foo being changed inside the
>>> loop".

What is nasty to me is that to understand the loop, one must do a whole 
program analysis to determine both that 'iters' is not rebound and that 
the list it is bound to is not mutated.  To do the later, one must not 
only read the loop body, but also preceding code to make sure the list 
is not aliased.

 > iters is empty if and only if args is empty.
> If args is empty, iters should not be created.
>
> if args:
>    iters = ...
>    while True
>      ... (return on exception)
>
> makes the logic clear.

Once the logic is clear and 'localized', even a simple compiler like 
CPython's can see that this is a loop-forever construct and that the 
loop test is unnecessary.  So it can be removed.

 >>> dis("while a: b+=1")
   1           0 SETUP_LOOP              20 (to 23)
         >>    3 LOAD_NAME                0 (a)
               6 POP_JUMP_IF_FALSE       22
               9 LOAD_NAME                1 (b)
              12 LOAD_CONST               0 (1)
              15 INPLACE_ADD
              16 STORE_NAME               1 (b)
              19 JUMP_ABSOLUTE            3
         >>   22 POP_BLOCK
         >>   23 LOAD_CONST               1 (None)
              26 RETURN_VALUE

 >>> dis("while True: b+=1")
   1           0 SETUP_LOOP              13 (to 16)
         >>    3 LOAD_NAME                0 (b)
               6 LOAD_CONST               0 (1)
               9 INPLACE_ADD
              10 STORE_NAME               0 (b)
              13 JUMP_ABSOLUTE            3
         >>   16 LOAD_CONST               1 (None)
              19 RETURN_VALUE

'while 1' and 'while "exception not raised"' are similarly condensed. 
This leaves only the initial test of the argument.

-- 
Terry Jan Reedy




More information about the Python-list mailing list