variables with loop-local scope?

B

Brian Alexander

I remember using a language many years ago that permitted the creation
of temporary, local variables within the body of a loop (and perhaps
other statement blocks.) Maybe it was Turing.

Can Python do this?

---

EX:
---

for i in listOfNames:
prefixMr = 'Mr'
prefixMs = 'Ms'

if i in mansName:
salutation = prefixMr + i

else:
salutation = prefixMs + i

print 'Hello,' + salutation

----

The idea is that all variables created within the for statements will be
forgotten once the loop exits. No need to exit the procedure.

Is this possible?

Many thanks,

Brian.
 
T

Terry Reedy

Brian Alexander said:
I remember using a language many years ago that permitted the creation
of temporary, local variables within the body of a loop (and perhaps
other statement blocks.) Maybe it was Turing.

Can Python do this?
for i in listOfNames:
prefixMr = 'Mr'
prefixMs = 'Ms'
if i in mansName:
salutation = prefixMr + i
else:
salutation = prefixMs + i
print 'Hello,' + salutation

The idea is that all variables created within the for statements will be
forgotten once the loop exits. No need to exit the procedure.

Having the induction variable remain set to its last value is
sometimes useful (and when searching for a match) and almost never a
bother. If and when it is, just delete it.

Terry J. Reedy
 
S

Skip Montanaro

Brian> Can Python do this?

Sure:

for i in listOfNames:
prefixMr = 'Mr'
prefixMs = 'Ms'
if i in mansName:
salutation = prefixMr + i
else:
salutation = prefixMs + i
else:
del prefixMr
del prefixMs

print 'Hello,' + salutation

Probably not quite what you wanted. Is there a reason you need/want the
variable to disappear before the function returns?

Skip
 
A

Alex Martelli

Brian said:
I remember using a language many years ago that permitted the creation
of temporary, local variables within the body of a loop (and perhaps
other statement blocks.) Maybe it was Turing.

Or C (not that exotic, but does have block-local variables, as do its
descendants).
Can Python do this?

Python's variables _automatically_ go out of scope only when a function
terminates (you can of course explicitly delete them). So, if you need
"automatic going out of scope", you need a nested function. E.g.:
for i in listOfNames:
prefixMr = 'Mr'
prefixMs = 'Ms'

if i in mansName:
salutation = prefixMr + i

else:
salutation = prefixMs + i

print 'Hello,' + salutation

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()


Alex
 
B

Brian Alexander

Skip said:
Brian> Can Python do this?

Sure:

for i in listOfNames:
prefixMr = 'Mr'
prefixMs = 'Ms'
if i in mansName:
salutation = prefixMr + i
else:
salutation = prefixMs + i
else:
del prefixMr
del prefixMs

print 'Hello,' + salutation

Probably not quite what you wanted. Is there a reason you need/want the
variable to disappear before the function returns?

Skip

Yes, it seems this is one way of doing it. The reason I was interested
is that it can reduce worries in a procedure that may have many local
variables. A large number of locals with very limited (sub-procedural)
scope is better than a large number of locals with procedural scope. (Of
course, having few locals is best of all.)

Brian.
 
B

Brian Alexander

Alex said:
Brian Alexander wrote:




Or C (not that exotic, but does have block-local variables, as do its
descendants).




Python's variables _automatically_ go out of scope only when a function
terminates (you can of course explicitly delete them). So, if you need
"automatic going out of scope", you need a nested function. E.g.:




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()


Alex

Alex;

Many thanks. This is quite interesting.

Brian.
 
A

Alex Martelli

Brian Alexander wrote:
...
...
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@lancelot bo]$ timeit.py -c -s'import aa' 'aa.with_block()'
100 loops, best of 3: 2.1e+03 usec per loop

[alex@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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top