A C-like if statement

B

Bob Greschke

I miss being able to do something like this in Python

1f (I = a.find("3")) != -1:
print "It's here: ", I
else:
print "No 3's here"

where I gets assigned the index returned by find() AND the if statement gets
to do its job in the same line. Then you don't have to have another like
that specifically gets the index of the "3". Is there a way to do this in
Python?

Thanks!

Bob
 
R

Roy Smith

Bob Greschke said:
I miss being able to do something like this in Python

1f (I = a.find("3")) != -1:
print "It's here: ", I
else:
print "No 3's here"

where I gets assigned the index returned by find() AND the if statement gets
to do its job in the same line. Then you don't have to have another like
that specifically gets the index of the "3". Is there a way to do this in
Python?

It is a deliberate and fundamental design decision in Python that
assignment is a statement, not an expression with side effects. This
means you often need an "extra" line compared to a classic C "assign
and test" idiom such as you have above. I, like you, often miss the
compactness of the C idiom, but there it is.

It's also unpythonic to return magic values to indicate failure.
Throwing an exception would be the more normal way of doing it. So,
I'd expect the above to translate into something like:

try:
i = a.find("3")
print "It's here: ", i
except NotFound:
print "No 3's here"
 
B

Bob Greschke

Roy Smith said:
It is a deliberate and fundamental design decision in Python that
assignment is a statement, not an expression with side effects. This
means you often need an "extra" line compared to a classic C "assign
and test" idiom such as you have above. I, like you, often miss the
compactness of the C idiom, but there it is.

It's also unpythonic to return magic values to indicate failure.
Throwing an exception would be the more normal way of doing it. So,
I'd expect the above to translate into something like:

try:
i = a.find("3")
print "It's here: ", i
except NotFound:
print "No 3's here"

Nuts. I guess you're right. It wouldn't be proper. Things are added or
proposed every day for Python that I can't even pronounce, but a simple 'if
(I = a.find("3")) != -1' isn't allowed. Huh. It might be time to go back
to BASIC. :)

I think your way would work if .find() were replaced with .index(). I'm
just trying to clean up an if/elif tree a bit, so using try would make
things bigger.

Thanks!

Bob
 
G

Giles Brown

But maybe we're talking about string methods so to get an exception
we'd want to use "index" instead of "find".

Giles
 
D

Dave Hansen

news:[email protected]... [...]
try:
i = a.find("3")
print "It's here: ", i
except NotFound:
print "No 3's here"

Nuts. I guess you're right. It wouldn't be proper. Things are added or
proposed every day for Python that I can't even pronounce, but a simple 'if
(I = a.find("3")) != -1' isn't allowed. Huh. It might be time to go back
to BASIC. :)

I think you'll find that BASIC doesn't allow it either...

Of the "missing" "features" of Python, this one is waaaaaay down on my
list. In fact, it's not there at all. What I _really_ miss is
do{...}while. The best workaround I've found is unaesthetic, IMHO:

while 1:
# stuff
if exit_condition: break

Regards,
-=Dave
 
S

Steven D'Aprano

Nuts. I guess you're right. It wouldn't be proper. Things are added or
proposed every day for Python that I can't even pronounce, but a simple 'if
(I = a.find("3")) != -1' isn't allowed. Huh. It might be time to go back
to BASIC. :)

There are *reasons* why Python discourages functions with side-effects.
Side-effects make your code hard to test and harder to debug.
I think your way would work if .find() were replaced with .index(). I'm
just trying to clean up an if/elif tree a bit, so using try would make
things bigger.

Then write a function! Instead of calling the try..except block in every
branch directly, pull it out into a function:

def test(s,what):
try:
i = s.index(what)
print "It's here: ", i
except ValueError:
print "No 3's here"
 
B

bonono

Steven said:
There are *reasons* why Python discourages functions with side-effects.
Side-effects make your code hard to test and harder to debug.
Traceback (most recent call last):
File "<pyshell#0>", line 1, in -toplevel-
"test".index("a")
ValueError: substring not found-1
 
P

Paul Rubin

Bob Greschke said:
I miss being able to do something like this in Python

1f (I = a.find("3")) != -1:
print "It's here: ", I
else:
print "No 3's here"

where I gets assigned the index returned by find() AND the if statement gets
to do its job in the same line. Then you don't have to have another like
that specifically gets the index of the "3". Is there a way to do this in
Python?

For regexps I sometimes do it with a specially created class instance.
Something like:

save = Cache_match()

if save.find(a, "3"):
print "it's here:", save.result
else:
print "no 3's here"

Implementing Cache_match is left to you as an exercise. It does make
your code a bit cleaner if you're doing lots of matching.
 
T

Terry Hancock

There are *reasons* why Python discourages functions with
side-effects. Side-effects make your code hard to test and
harder to debug.

You of course meant "expressions with side-effects". Python
is pretty good at making functions with side-effects. At
least it is if you want them. ;-)
 
S

Steven D'Aprano

You of course meant "expressions with side-effects". Python
is pretty good at making functions with side-effects. At
least it is if you want them. ;-)

Yes, of course I meant that.

However, functions with side-effects are also discouraged. Unless
side-effects are the correct way to do whatever it is you are trying to
do, in which case they are encouraged.

*wink*
 
S

Steven D'Aprano

Traceback (most recent call last):
File "<pyshell#0>", line 1, in -toplevel-
"test".index("a")
ValueError: substring not found
-1


Did you have a point?

In case you haven't been following the entire thread, the original bit of
code above (the try block using the find method) wasn't mine. It just
happened to be quoted in my post.


Now that's a Python wart: using >>> for the prompt for interactive
sessions. It makes it ambiguous when posting code in email or newsgroups,
especially once the code gets quoted a few times.
 
B

bonono

Steven said:
Did you have a point?
It was about your side-effect talk, if you failed to see it, that is
fine.

BTW, it seems that the term side-effect of function used is a bit
different from my understanding of how it is in general used in this
field.
 
S

Steven D'Aprano

It was about your side-effect talk, if you failed to see it, that is
fine.

BTW, it seems that the term side-effect of function used is a bit
different from my understanding of how it is in general used in this
field.

What side effect?

Returning magic values (e.g. -1 to indicate "not found") is not a
side-effect in any terminology I've come across.

A side-effect would be if s.index(substr) not only returned the index as
promised, but also (say) appended substr to a list somewhere.

Side-effects aren't always bad (import, for example, does all its work by
side-effect). But they are generally frowned upon, and in functional
languages they are verboten.
 
K

Kent Johnson

Steven said:
Now that's a Python wart: using >>> for the prompt for interactive
sessions. It makes it ambiguous when posting code in email or newsgroups,
especially once the code gets quoted a few times.

So change it. My pythonstartup.py contains:

import sys
sys.ps1 = ' >>> '
sys.ps2 = ' ... '

Kent
 
A

Antoon Pardon

Op 2006-02-23 said:
It is a deliberate and fundamental design decision in Python that
assignment is a statement, not an expression with side effects.

The only motivation I have heard for this decision is to easily
find typo related bugs. I can hardly find that a fundamental
design decision.
 
S

Steven D'Aprano

So change it. My pythonstartup.py contains:

import sys
sys.ps1 = ' >>> '
sys.ps2 = ' ... '

Sure, I can change my prompt. And you can change yours. And Bob can change
his. And Freddy doesn't bother. And now we've all got different prompts,
and nobody knows what's what...

It is good to be able to set your own prompt when needed. But it is also
good to have a common default prompt. And it would be good for that common
default prompt to NOT clash with email quoting standards. Therefore that
the prompt actually does clash is a wart.

That's my opinion. Yours may differ.
 
R

Roy Smith

Steven D'Aprano said:
Side-effects aren't always bad (import, for example, does all its work by
side-effect). But they are generally frowned upon, and in functional
languages they are verboten.

How do you do any I/O in a functional language if side effects are
verboten? For that matter, how does a functional program ever stop running?
 
R

Rene Pijlman

Roy Smith:
How do you do any I/O in a functional language if side effects are
verboten?

The user is a function. Output is its parameter, input its return value.
The user is not allowed to maintain state ;-)
For that matter, how does a functional program ever stop running?

By returning to the caller.
 
S

Steven D'Aprano

How do you do any I/O in a functional language if side effects are
verboten? For that matter, how does a functional program ever stop running?

Fair enough.

But still, ignoring unavoidable cases like writing to a file, the ideal of
functional languages is for side-effects to not exist.
 
D

Diez B. Roggisch

Roy said:
How do you do any I/O in a functional language if side effects are
verboten? For that matter, how does a functional program ever stop
running?

Using Monads. Which basically starts carrying around explicit state in an
implicit manner. But that is restricted to very few, specific portions of
the program.

Diez
 

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
474,285
Messages
2,571,416
Members
48,107
Latest member
AmeliaAmad

Latest Threads

Top