[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Bearophile

3/4/2008 1:28:00 PM

So far in Python I've almost hated the 'else' of the 'for' loops:
- I have problems to remember its meaning;
- It gives me little problems when I later want to translate Python
code to other languages (and you always have to translate long-lived
code).
- I have used it only once, so far.

So so far I'd liked to see it removed from Python 3.0.

But then this article:
http://tratt.net/laurie/tech_articles/articles/the_high_risk_of_novel_languag...
has shown me that my problems with the 'else' of the 'for' mostly come
from just its bad naming. The converge language is yet another very
Python-like language, and it uses a better naming (the word
"exhausted" is long and has a complex spelling for non-English
speakers, so it's not perfect):

for ...:
...
exhausted:
...
broken:
...

The meaning is explicit. While "else" seems to mean little there.
So I may like something similar for Python 3.x (or the removal of the
"else").

Bye,
bearophile
24 Answers

Carl Banks

3/4/2008 3:18:00 PM

0

On Mar 4, 8:27 am, bearophileH...@lycos.com wrote:
> So far in Python I've almost hated the 'else' of the 'for' loops:
> - I have problems to remember its meaning;
> - It gives me little problems when I later want to translate Python
> code to other languages (and you always have to translate long-lived
> code).
> - I have used it only once, so far.
>
> So so far I'd liked to see it removed from Python 3.0.
>
> But then this article:http://tratt.net/laurie/tech_articles/articles/the_high_ris......
> has shown me that my problems with the 'else' of the 'for' mostly come
> from just its bad naming. The converge language is yet another very
> Python-like language, and it uses a better naming (the word
> "exhausted" is long and has a complex spelling for non-English
> speakers, so it's not perfect):
>
> for ...:
> ...
> exhausted:
> ...
> broken:
> ...
>
> The meaning is explicit. While "else" seems to mean little there.
> So I may like something similar for Python 3.x (or the removal of the
> "else").


I would not be opposed to this on its own merits, but there is a
rationale behind the name "else". If you consider a for loop to be a
rolled-up if...elif...else statement (situations where this is
reasonable tend to be the same ones were else would be useful), then
the "else" clause would remain unchanged on the for loop.

For instance, if you have a (trivial) if...elif...else like this:

if a == 0:
do_task_0()
elif a == 1:
do_task_1()
elif a == 2:
do_task_2()
else:
do_default_task()

You could roll it up into a for...else statement like this:

for i in range(3):
if a == i:
do_task[a]()
else:
do_default_task()

(Please never mind the trivialness of this example; I know you can
eliminate the for loop altogether; this is JUST an example.)

I keep this analogy in mind when using for...else to keep the
semantics straight.


Carl Banks

Björn Lindqvist

3/4/2008 3:55:00 PM

0

On Tue, Mar 4, 2008 at 4:17 PM, Carl Banks <pavlovevidence@gmail.com> wrote:
> > for ...:
> > ...
> > exhausted:
> > ...
> > broken:
> > ...
> >
> > The meaning is explicit. While "else" seems to mean little there.
> > So I may like something similar for Python 3.x (or the removal of the
> > "else").
>
>
> I would not be opposed to this on its own merits, but there is a
> rationale behind the name "else". If you consider a for loop to be a
> rolled-up if...elif...else statement (situations where this is
> reasonable tend to be the same ones were else would be useful), then
> the "else" clause would remain unchanged on the for loop.
>
> For instance, if you have a (trivial) if...elif...else like this:
>
> if a == 0:
> do_task_0()
> elif a == 1:
> do_task_1()
> elif a == 2:
> do_task_2()
> else:
> do_default_task()
>
> You could roll it up into a for...else statement like this:
>
> for i in range(3):
> if a == i:
> do_task[a]()
> else:
> do_default_task()

You forgot the break statement. The else suite will always be executed
in this loop. Kind of proves bearophiles point, for-else is really
tricky.


--
mvh Björn

Tim Chase

3/4/2008 4:00:00 PM

0

> For instance, if you have a (trivial) if...elif...else like this:
>
> if a == 0:
> do_task_0()
> elif a == 1:
> do_task_1()
> elif a == 2:
> do_task_2()
> else:
> do_default_task()
>
> You could roll it up into a for...else statement like this:
>
> for i in range(3):
> if a == i:
> do_task[a]()

important "break" missing here...

> else:
> do_default_task()


or otherwise this code will do_task_i *and* do_default_task()...

-tkc


Carl Banks

3/4/2008 5:05:00 PM

0

On Mar 4, 10:55 am, "BJörn Lindqvist" <bjou...@gmail.com> wrote:
> On Tue, Mar 4, 2008 at 4:17 PM, Carl Banks <pavlovevide...@gmail.com> wrote:
> > > for ...:
> > > ...
> > > exhausted:
> > > ...
> > > broken:
> > > ...
>
> > > The meaning is explicit. While "else" seems to mean little there.
> > > So I may like something similar for Python 3.x (or the removal of the
> > > "else").
>
> > I would not be opposed to this on its own merits, but there is a
> > rationale behind the name "else". If you consider a for loop to be a
> > rolled-up if...elif...else statement (situations where this is
> > reasonable tend to be the same ones were else would be useful), then
> > the "else" clause would remain unchanged on the for loop.
>
> > For instance, if you have a (trivial) if...elif...else like this:
>
> > if a == 0:
> > do_task_0()
> > elif a == 1:
> > do_task_1()
> > elif a == 2:
> > do_task_2()
> > else:
> > do_default_task()
>
> > You could roll it up into a for...else statement like this:
>
> > for i in range(3):
> > if a == i:
> > do_task[a]()
> > else:
> > do_default_task()
>
> You forgot the break statement. The else suite will always be executed
> in this loop. Kind of proves bearophiles point, for-else is really
> tricky.

Ah ha, but that would have been a mistake with or without the else
clause....


Carl Banks

Shane Geiger

3/4/2008 6:08:00 PM

0


> if a == 0:
> do_task_0()
> elif a == 1:
> do_task_1()
> elif a == 2:
> do_task_2()
> else:
> do_default_task()

The if-elif-else structure that calls functions (like that above) can be
avoided with the code below:


def foo0(): print 'foo0'
def bar0(): print 'bar0'
def foo1(): print 'foo1'
def bar1(): print 'bar1'
def do_default_task(): print 'do_default_task'

do_task = { 0:foo0, 1:foo1, 2:bar0, 3:bar1, }

a = 1

# example of normal usage
if a in do_task.keys(): do_task[a]()
else: do_default_task()

# example of testing all functions in the dict as well as the default
function
for a in do_task.keys() + [8]: # 8 is a non-existent key in the do_task
dict
print "a is ",a,"and it gives this output:",
if a in do_task.keys(): do_task[a]()
else: do_default_task()





Carl Banks wrote:
> On Mar 4, 10:55 am, "BJörn Lindqvist" <bjou...@gmail.com> wrote:
>
>> On Tue, Mar 4, 2008 at 4:17 PM, Carl Banks <pavlovevide...@gmail.com> wrote:
>>
>>> > for ...:
>>> > ...
>>> > exhausted:
>>> > ...
>>> > broken:
>>> > ...
>>>
>>> > The meaning is explicit. While "else" seems to mean little there.
>>> > So I may like something similar for Python 3.x (or the removal of the
>>> > "else").
>>>
>>> I would not be opposed to this on its own merits, but there is a
>>> rationale behind the name "else". If you consider a for loop to be a
>>> rolled-up if...elif...else statement (situations where this is
>>> reasonable tend to be the same ones were else would be useful), then
>>> the "else" clause would remain unchanged on the for loop.
>>>
>>> For instance, if you have a (trivial) if...elif...else like this:
>>>
>>> if a == 0:
>>> do_task_0()
>>> elif a == 1:
>>> do_task_1()
>>> elif a == 2:
>>> do_task_2()
>>> else:
>>> do_default_task()
>>>
>>> You could roll it up into a for...else statement like this:
>>>
>>> for i in range(3):
>>> if a == i:
>>> do_task[a]()
>>> else:
>>> do_default_task()
>>>
>> You forgot the break statement. The else suite will always be executed
>> in this loop. Kind of proves bearophiles point, for-else is really
>> tricky.
>>
>
> Ah ha, but that would have been a mistake with or without the else
> clause....
>
>
> Carl Banks
>

This approach works well for me:



def foo0(): print 'foo0'
def bar0(): print 'bar0'
def foo1(): print 'foo1'
def bar1(): print 'bar1'

def do_default_task(): print 'do_default_task'

do_task = { 0:foo0, 1:foo1, 2:bar0, 3:bar1, }

a = 1

# example of normal usage
if a in do_task.keys(): do_task[a]()
else: do_default_task()


# example of testing
for i in range(len(do_task.keys)):
if a in do_task.keys(): do_task[a]()
else: do_default_task()



--
Shane Geiger
IT Director
National Council on Economic Education
sgeiger@ncee.net | 402-438-8958 | http://ww...

Leading the Campaign for Economic and Financial Literacy

Aaron Brady

3/4/2008 6:40:00 PM

0

Would you like it to be removed or its name changed?

You can do it with a special iteration:

for a in B:
if behavior
break
else:
2behavior

---->

class KeepResult:...
kr= KeepResult( B )
for a in kr:
if behavior
break
if kr.diditbreak?:
2behavior
(if not:
3behavior)

It just can't do automatic continues; you'd need a
kr.i'mcontinuingonthisone(). Would that be useful in addition?

Jeffrey Froman

3/4/2008 7:22:00 PM

0

Carl Banks wrote:

> there is a
> rationale behind the name "else".  If you consider a for loop to be a
> rolled-up if...elif...else statement

This is an interesting angle. I've always considered "for/else" to be
unintuitive, not because of "else", but because of the coupling with "for".
Instead, I think of this as a "break/else" statement, and everything gels
for me. The same applies to my comprehension of "while/else".

I wonder how this came to be called "for/else" or "for-else". I haven't
spotted that expression in the python docs yet.

With whatever name, I find the construct quite elegant and regularly useful.


Jeffrey


Raymond Hettinger

3/4/2008 8:10:00 PM

0

[BearOphile]
> So far in Python I've almost hated the 'else' of the 'for' loops

FWIW, I'm very happy with for-else. Most of the time, you don't need
it, but when you do, it beats the heck out of doing silly tricks with
flags.

The primary use case is searching a container:

prep_tasks()
for item in container:
if predicate(item):
found_tasks()
break
else:
not_found_tasks()
follow_up_tasks

Raymond

Bearophile

3/4/2008 8:27:00 PM

0

Raymond HettInger:
> FWIW, I'm very happy with for-else. Most of the time, you don't need
> it, but when you do, it beats the heck out of doing silly tricks with
> flags.

I'd like it to be renamed to something more natural :-)

Bye,
bearophile

Terry Reedy

3/4/2008 9:41:00 PM

0


<bearophileHUGS@lycos.com> wrote in message
news:c4921e6c-119f-4306-8e89-c436c3cb6f6d@u69g2000hse.googlegroups.com...
| So far in Python I've almost hated the 'else' of the 'for' loops:
| - I have problems to remember its meaning;

Consider the following pseudoPython which you should understand:

label: loop
if cond:
do_something()
goto loop
else:
do_else()

We actually write the above as

while cond:
do_something()
else:
do_else()

Same meaning; do_else is executed when condition is false.

A for-loop is equivalent to a while loop with the condition 'iterator is
not exhausted'. So do_else when that condition is false -- the iterator is
exhausted.

Terry Jan Reedy