473,394 Members | 1,746 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

No "side effect" assignment!

Ok,

I miss the idiom that my other languages use,
something like:
while( foo = getmore()){
process(foo);
}
I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()
Is that what ppl do? The manual sez that this is
so that newbs won't do:

if foo = bar:
process()

thinking that they are checking for equality.
I feel that in a few ways python suffers by catering
to the uninitiated. Usually however, there are
great workarounds (or even plain better ways to do the job),
which I am hopeful will be yielded by the list, as has
been it's record thus far to do.

Thanks,

Tobiah

Jul 18 '05 #1
17 3040
Tobiah wrote:

[snip]


I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()


Then test your gag reflex on the following:

while 1:
foo = getmore()
if not foo:
break
process(foo)

Slips down pretty smoothly with me.

[snip]

Dave

--
Dave Kuhlman
http://www.rexx.com/~dkuhlman
dk******@rexx.com
Jul 18 '05 #2
Ack!!! (slight gag reflex) :)

That's actually more lines, even if more readable.

Ok, my perl roots are showing, but I was thinking
of putting the following function into my standard
module:

def eq(thingy):
global _
_ = thingy
return _

Having done that, I can now say:

while eq(getmore()):
process(_)
It seems to me that adding support for the side effect
assignment would not break any existing scripts. Gee,
they did it for += ;)

Thanks,

Tobiah
Then test your gag reflex on the following:

while 1:
foo = getmore()
if not foo:
break
process(foo)

Slips down pretty smoothly with me.

[snip]

Dave


Jul 18 '05 #3

"Tobiah" <to**@rcsreg.com> wrote in message
news:0f******************************@news.teranew s.com...
Ok,

I miss the idiom that my other languages use,
something like:
while( foo = getmore()){
process(foo);
}
I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()
Is that what ppl do? The manual sez that this is
so that newbs won't do:

if foo = bar:
process()

thinking that they are checking for equality.
I feel that in a few ways python suffers by catering
to the uninitiated. Usually however, there are
great workarounds (or even plain better ways to do the job),
which I am hopeful will be yielded by the list, as has
been it's record thus far to do.
While one of Guido's reasons for not including assignment
as an expression was to avoid errors (and that's not always
a novice error,) Python provides similar functionality in the
'for' statement. In C, C++ and Java, 'for' is basically
syntactic sugar around a loop, in Python, it actually does
an assignment of the next element of a sequence.

Your example could be:

for foo in getmore:
process(foo)

as long as getmore is either a sequence or implements the
iterator protocol.

This isn't a total replacement for assignment as an expression,
but it does cover the overwhelming majority of use cases.

John Roth


Thanks,

Tobiah

Jul 18 '05 #4
"Tobiah" <to**@rcsreg.com> wrote in message
news:0f******************************@news.teranew s.com...
Ok,

I miss the idiom that my other languages use,
something like:
while( foo = getmore()){
process(foo);
}

[snip]

If you must use assignments in expressions, you might find the following
recipes useful:
http://aspn.activestate.com/ASPN/Coo.../Recipe/202234
http://aspn.activestate.com/ASPN/Coo...n/Recipe/66061

Jul 18 '05 #5
Tobiah> Ack!!! (slight gag reflex) :)
Tobiah> That's actually more lines, even if more readable.

Tobiah> Ok, my perl roots are showing, but I was thinking
Tobiah> of putting the following function into my standard
Tobiah> module:

Tobiah> def eq(thingy):
Tobiah> global _
Tobiah> _ = thingy
Tobiah> return _

Tobiah> Having done that, I can now say:

Tobiah> while eq(getmore()):
Tobiah> process(_)

You're right -- your Perl roots are showing.

How about this instead:

def make_generator(func):
while x = func():
yield x

for val in make_generator(getmore):
process(val)

--
Andrew Koenig, ar*@acm.org
Jul 18 '05 #6
Andrew Koenig wrote:
How about this instead:

def make_generator(func):
while x = func():

^^^^^^^^^^

Not too likely in Python :-).

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Youth is a period of missed opportunities.
\__/ Cyril Connolly
Jul 18 '05 #7
Erik Max Francis wrote:
Andrew Koenig wrote:

How about this instead:

def make_generator(func):
while x = func():


^^^^^^^^^^

Not too likely in Python :-).


Heh! My point exactly :)

Jul 18 '05 #8
Dave Kuhlman <dk******@rexx.com> wrote in message news:<bk************@ID-139865.news.uni-berlin.de>...
Tobiah wrote:

[snip]


I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()


Then test your gag reflex on the following:

while 1:
foo = getmore()
if not foo:
break
process(foo)

Slips down pretty smoothly with me.

[snip]

Dave


I am alone in feeling some slight unease at the sight of "while 1: ...
break"? I know this is considered somewhat pythonic, but apart from
the fact that there is only a single assignment statement is there
really any advantage to be gained by doing it this way? It seems to
be trading one aesthetic disadvantage for another, and imho, a
marginally less legible one.

In terms of pandering to newbies, I think the requirement that loop
conditions be expressions is much more squarely aimed at experienced
programmers, who would otherwise be tempted to write unintelligible
code by placing too much of the programs logic withing the loop
condition.
Jul 18 '05 #9
Tobiah <to**@rcsreg.com> wrote in
news:0f******************************@news.teranew s.com:
I can't seem to do this in python without gagging:

foo = getmore()
while foo:
process(foo)
foo = getmore()
Is that what ppl do?


I don't know about ppl, but Python programmers have a variety of ways of
structuring this code. The one that I think is simplest, but is often
overlooked is to use the builtin function 'iter'. It won't exactly replace
the code you have above, since your loop terminates as soon as getmore()
returns anything false (None, 0, False, '' would all terminate it). If
however you know the exact value to indicate termination (I'll guess
getmore() returns None when its done), you can write your loop:

for foo in iter(getmore, None):
process(foo)

If instead of a simple function call you had a more complex expression (say
getmore took a file as an argument), you might consider a lambda:

for foo in iter(lambda: getmore(aFile), None):
process(foo)
--
Duncan Booth du****@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
Jul 18 '05 #10
Asun Friere wrote:

Dave Kuhlman wrote:
while 1:
foo = getmore()
if not foo:
break
process(foo)


I am alone in feeling some slight unease at the sight of "while 1: ...
break"? I know this is considered somewhat pythonic, but apart from
the fact that there is only a single assignment statement is there
really any advantage to be gained by doing it this way? It seems to
be trading one aesthetic disadvantage for another, and imho, a
marginally less legible one.


There is a distinct advantage in the above, over the form with
a duplicated line, and it's nothing to do with aesthetics. Sure,
they both may be ugly to you (but they feel quite simple and thus
elegant to some experienced Python programmers), but the real issue
is that the one has the duplicated assignment and is therefore prone
to maintenance problems. This fact alone far outweighs any aesthetic
consideration, and wholly justifies the above form.

If you are really offended, use a wrapper of some kind as others have
shown.

-Peter
Jul 18 '05 #11
af*****@yahoo.co.uk (Asun Friere) writes:
I am alone in feeling some slight unease at the sight of "while 1: ...
break"? I know this is considered somewhat pythonic, but apart from
the fact that there is only a single assignment statement is there
really any advantage to be gained by doing it this way? It seems to
be trading one aesthetic disadvantage for another, and imho, a
marginally less legible one.


While I agree with you, I don't think I'd bother with changing thel
language now to fix it. If I were writing a new language I'd prefer a
loop-and-a-half structure something like this:

repeat:
stuff
while test:
stuff

I'd really prefer something like the above without the second colon.
While it's nice to have the condition dedented for readability, it
isn't really starting a new block. At any rate, I don't think adding
this to the current language is worth it, so I'll keep using "while 1:
break" structures and translating to the above in my head.

--
Christopher A. Craig <li*********@ccraig.org>
"So we who are many, are one body in Christ, and individually members
one of another." Romans 12:5 (NASB)
Jul 18 '05 #12
Tobiah <to**@rcsreg.com> writes:
Erik Max Francis wrote:
Andrew Koenig wrote:
How about this instead:

def make_generator(func):
while x = func():

^^^^^^^^^^
Not too likely in Python :-).


Heh! My point exactly :)


def f(): return raw_input()

for x in iter(f, ""):
print x
If you want to be more vague about the sentinel (a bad idea, and
equivalent to your Perl example), I suppose you could use something
obscure like this:

class FalsehoodSentinel:
def __cmp__(self, other): return int(bool(other))
falsehoodsentinel = FalsehoodSentinel()
and then:

def f(): return raw_input()

for x in iter(f, falsehoodsentinel):
print x
So that *any* false value from f will end the for loop. Don't do
that, though -- explicit is better...

Of course, most of the time, having written your program Pythonishly,
not Perlishly, you'll have iterators in the first place, and won't
need to turn them into an iterator by hand.
John
Jul 18 '05 #13

"John J. Lee" <jj*@pobox.com> wrote in message
news:87************@pobox.com...
def f(): return raw_input()

for x in iter(f, ""):
print x


Nice -- I keep forgetting about iter() -- except that the wrapper
adds nothing that I can see.
for l in iter(raw_input, ''): print '*', l, '*' ....
aksjf
* aksjf *
jslfkj
* jslfkj *


Terry J. Reedy

Jul 18 '05 #14
Asun Friere <af*****@yahoo.co.uk> wrote:
In terms of pandering to newbies, I think the requirement that loop
conditions be expressions is much more squarely aimed at experienced
programmers, who would otherwise be tempted to write unintelligible
code by placing too much of the programs logic withing the loop
condition.


Uhm, no. *Experienced* programmers know better than to take usch
things to excess, unless the code is being written for a obfuscated
code contest. As is so often the case, it's those difficult
in-betweeners, no longer innocent by virtue of ignorance, not yet
grown wise enough to eschew the merely clever, who bollix it all up for
the rest of us.

--
Threaten not the comic with your lawyers' bluster,
all toothless to supress parody and satire;
for you will not amuse him, but you may inspire him.
(me, inspired by http://www.netfunny.com/rhf/jokes/01/Apr/mcrhf.html)
Jul 18 '05 #15
Sean Ross <sr***@connectmail.carleton.ca> wrote:
If you must use assignments in expressions, you might find the following
recipes useful:
http://aspn.activestate.com/ASPN/Coo.../Recipe/202234
Did I forget about this one or is it in fact new? It is, as the author
says, an ugly hack at the implementation level, but that seems to be
its only drawback. It doesn't use any hidden state that could be
altered unexpectedly, and is only a minor eyesore; those who worry
about accidentally writing an assignment in place of an equality test
will consider that last to be a feature, of course. Perhaps it could
be improved, slightly, by being renamed to "let"? <evil grin>
http://aspn.activestate.com/ASPN/Coo...n/Recipe/66061


The hope of obliterating this recipie is IMO the strongest argument in
favor of adding operator= to Python. I can think of no reason to
prefer this to 202234 aside from the chance that the language
implementation detail used in the latter's implementation could
conceivably go away someday.

Short form: 66061 Considered Harmful. What, you thought it was just a
coincidence it had all those sixes in its number?

--
People make secure systems insecure because
insecure systems do what people want and
secure systems don't. -- James Grimmelmann
Jul 18 '05 #16
"Martin Maney" <ma***@pobox.com> wrote in message
news:bk**********@wheel2.two14.net...
Sean Ross <sr***@connectmail.carleton.ca> wrote:
If you must use assignments in expressions, you might find the following
recipes useful:
http://aspn.activestate.com/ASPN/Coo.../Recipe/202234


Did I forget about this one or is it in fact new? It is, as the author
says, an ugly hack at the implementation level, but that seems to be
its only drawback.


I think that the other drawback is that it only works at the top level of a
module. If you are inside a function or method then the locals() (f_locals)
dictionary is still writeable but it has no effect on the namespace it
represents.

So ...

import sys
def set(**kw):
assert len(kw)==1

a = sys._getframe(1)
a.f_locals.update(kw)
return kw.values()[0]

def main():
A=range(10)

while set(x=A.pop()):
print x

main()

.... prints 0,0,0,0,0,0 etc instead of what you want.

I guess you might call "a.f_locals.update(kw)" a no-(side)-effect assignment
;)

Paul
Jul 18 '05 #17
Paul Paterson <pa**********@users.sourceforge.net> wrote:
I think that the other drawback is that it only works at the top level of a
module.
Yeah, it comes back to me now. So there's still nothing but ugly
and/or dangerous workarounds when you need to use a function's result
in a conditional as well as later on. Pytho is such a pleasant
language 95% of the time that the nastiness of the corner cases seems
worse than they rationally warrant - or maybe not, since these warts
tend to drop me out of flow and cost a lot more time than just
remebering the way(s) to hack around them.
I guess you might call "a.f_locals.update(kw)" a no-(side)-effect assignment


Sure 'nuff. Pity, it was otherwise quite a nice answer to what seems
to be an endlessly recurring issue.

--
Although we may never know with complete certainty the identity
of the winner of this year's presidential election, the identity
of the loser is perfectly clear. It is the nation's confidence
in the judge as an impartial guardian of the law.
- Justice John Paul Stevens, from his dissenting opinion Dec 12, 2000
Jul 18 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Miles Davenport | last post by:
I would like some advice on what Java server-side alternatives their are to an applet which is a shopping cart application which allows the user to drag-and-drop individual items into "an order"...
1
by: Andrew MacIntyre | last post by:
I'm seeing a bizarre situation where IndexErrors are being thrown with "tuple index out of range" error strings. The scenario is something like: l = for a, b in l: ...
2
by: pleaseSeeFooter | last post by:
Pythonagons, I am considering using (building) a client-side application, rather than a browser, for an Internet application. I am aware there are a few resourcesout there like XUL and various...
0
by: Charles | last post by:
I'm being tortured by this warning: Warning: Unknown(): Your script possibly relies on a session side-effect which existed until PHP 4.2.3. ... I've looked the code up and down and I'm no...
9
Death Slaught
by: Death Slaught | last post by:
I'm working on a web site, and every thing is fine except when I added the navagation bar......for some reason it pushes my navagation bar away from the border, which is odd because there's no reason...
10
by: Kurda Yon | last post by:
Hi, I set the register_globals off and try to get my code working under the new conditions. I stuck on the following problem: Warning: Unknown(): Your script possibly relies on a session side-...
0
by: diegocami | last post by:
Hi everyone!, I need some directions on how to get my "sweeping bar effect" to work, I´ll try to explain myself: Situation: I have a couple of buttons that should attach (that´s the method I´m...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.