variables with loop-local scope?

Alex Martelli aleax at aleax.it
Mon Oct 27 06:34:18 EST 2003


Brian Alexander wrote:
   ...
>> for i in listOfNames:
>>    def block():
>>      prefixMr = 'Mr'
>>      prefixMs = 'Ms'
>>  
>>      if i in mansName:
>>        salutation = prefixMr + i
>>      else:
>>        salutation = prefixMs + i
>>      print 'Hello,' + salutation
>>    block()
   ...
> Many thanks. This is quite interesting.

You're welcome!  One important detail: the name 'block' itself
does remain bound (to the function object) even after loop exit;
"del block" after the loop (or in the loop's "else" clause) is
the one way to get rid of it.  Performance effects aren't good
at all, either.  Consider the following file aa.py:

lotsofnames = ('carlo alex brian joe marco anna rosa kim'.split())*100
masculnames = dict.fromkeys('carlo alex brian joe marco'.split())

def with_block(listOfNames=lotsofnames, mansName=masculnames):
    for i in listOfNames:
       def block():
         prefixMr = 'Mr'
         prefixMs = 'Ms'
     
         if i in mansName:
           salutation = prefixMr + i
         else:
           salutation = prefixMs + i
         #print 'Hello,' + salutation
       block()

def without_block(listOfNames=lotsofnames, mansName=masculnames):
    for i in listOfNames:
         prefixMr = 'Mr'
         prefixMs = 'Ms'
     
         if i in mansName:
           salutation = prefixMr + i
         else:
           salutation = prefixMs + i
         #print 'Hello,' + salutation

and the measurements:

[alex at lancelot bo]$ timeit.py -c -s'import aa' 'aa.with_block()'
100 loops, best of 3: 2.1e+03 usec per loop

[alex at lancelot bo]$ timeit.py -c -s'import aa' 'aa.without_block()'
1000 loops, best of 3: 630 usec per loop

so, we're slowing the function down by over 3 times by repeating
the 'def' (and using nonlocal access for 'i' and 'mansName' in
the block, but that's minor, as can be verified by injecting those
names as locals via the "default arguments" idiom).  Thus, one
rarely puts a 'def' (or, for that matter, a 'class') inside a
loop -- the repetition really buys you nothing much, after all.


Alex





More information about the Python-list mailing list