Since George Sakkis proposed a new way of doing list comprehensions http://groups-beta.google.com/group/...ff1b81fa70c8a7
letting tuples-like objects (x,y,z=0) acting as functions on other
tuples I wonder why this would not be a good starting point of
rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
i.e. mapping tuples on other tuples. This is equivalent to
lambda x,y,z=0:(x,y,z)
But regarding tuples as actions by means of an arrow "->" would
generalize this idea:
Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
Regards Kay 37 2085
Kay Schluehr wrote: Since George Sakkis proposed a new way of doing list comprehensions
http://groups-beta.google.com/group/...ff1b81fa70c8a7
letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
i.e. mapping tuples on other tuples. This is equivalent to
lambda x,y,z=0:(x,y,z)
But regarding tuples as actions by means of an arrow "->" would generalize this idea:
Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
IMHO, it's just lambda in disguise, and I'm not sure it's more readable
than lambda. You'll have to provide more arguments (sorry for the pun
!-) to gain my adhesion. (NB : I could use this syntax without problem,
it's just that we already have a syntax for this).
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
On 21 Mar 2005 22:37:42 -0800, "Kay Schluehr" <ka**********@gmx.net>
wrote: Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
I think that there's too much implied, and that in the long run it,
if we keep addding in special shortcuts, it will lead to very dificult
to read code.
> letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
i.e. mapping tuples on other tuples. This is equivalent to
lambda x,y,z=0:(x,y,z)
As you say for yourself, that's just lambda in disguise. So I guess the same
arguments about the in- or exclusion of lambda apply here. I personally
like lambda, but _can_ live without it.
--
Regards,
Diez B. Roggisch
bruno modulix wrote: Kay Schluehr wrote:
Since George Sakkis proposed a new way of doing list comprehensions
http://groups-beta.google.com/group/...ff1b81fa70c8a7
letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
i.e. mapping tuples on other tuples. This is equivalent to
lambda x,y,z=0:(x,y,z)
which is in fact not a valid solution in the context of Georges'
problem... (or I failed to get it to work !-)
But regarding tuples as actions by means of an arrow "->" would generalize this idea:
Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
IMHO, it's just lambda in disguise, and I'm not sure it's more readable than lambda. You'll have to provide more arguments (sorry for the pun !-) to gain my adhesion. (NB : I could use this syntax without problem, it's just that we already have a syntax for this).
Changing my mind after a more torough re-reading of the original thread
and few tests... The original problem is about tuple unpacking. The
proposed solution solves this problem, *and* can (could ?) be a
replacement for lambdas.
hmmm... I like the idea of having a more flexible tuple unpacking with a
function-call-like semantic, but I'm still not sure to like the idea of
replacing lambda with the proposed syntax.
needs-some-more-thinking-on-this-ly'yrs
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Diez B. Roggisch wrote: letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
i.e. mapping tuples on other tuples. This is equivalent to
lambda x,y,z=0:(x,y,z)
As you say for yourself, that's just lambda in disguise.
Not exactly in fact - unless I messed something. There are 2 problems
here: a more flexible tuple unpacking, *and* a lambda in disguise.
Actually, I'd go + 1 for the first, -1 for the second
So I guess the same arguments about the in- or exclusion of lambda apply here.
For the second part, yes. Not for the first one.
I personally like lambda, but _can_ live without it.
Yes, one can live without...
<troll>
....and without list comprehensions, __call__ and other special methods,
descriptors, metaclasses, first class functions, builtin datatypes like
lists and dicts, exceptions, dynamic typing, garbage collection, etc
too. Hurray, let's all happily program in assembly !-)
</troll>
--
bruno desthuilliers
ruby -e "print 'o****@xiludom.gro'.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"
> Not exactly in fact - unless I messed something. There are 2 problems here: a more flexible tuple unpacking, *and* a lambda in disguise. Actually, I'd go + 1 for the first, -1 for the second
The proposed syntax from Kay is lambda in disguise. To make it work like
George want it is modifying the unpacking behaviour. Actually while Kay
proposed his syntax as result of the discussion started by George it won't
work for that case. The reason is simply that the lambda form returns a
tuple, but does not make any revelations about the variable names that
tuple shall be unpacked to.
So they are in fact unrelated - at least if introduced as declared. An
augmentation to fulfill George's wishes could look like this:
[a,b,c for a,b,c: (x,y,z=0)-> x,y,z) in values]
Yes, one can live without... <troll> ...and without list comprehensions, __call__ and other special methods, descriptors, metaclasses, first class functions, builtin datatypes like lists and dicts, exceptions, dynamic typing, garbage collection, etc too. Hurray, let's all happily program in assembly !-) </troll>
You are right, but for lambda in its current limited form short, named
functions are a good replacement. I don't want to get rid of lambda - but
since listcomps got introduced, 95% of my usages of them disappeared.
--
Regards,
Diez B. Roggisch
On Tue, 22 Mar 2005 15:05:55 +0100, bruno modulix <on***@xiludom.gro>
wrote: bruno modulix wrote: Kay Schluehr wrote:
Since George Sakkis proposed a new way of doing list comprehensions
letting tuples-like objects (x,y,z=0) acting as functions on other tuples I wonder why this would not be a good starting point of rethinking anonymus functions?
In Georges proposition the action is
(x,y,z=0) -> (x,y,z)
What about a safe exec as a replacement to lamba but witht he
flexability of exec in a safe and limeted way?
safe_exec ( (*inputs) , (expressionstring) , ( *outputs) )
Functon to return a default value: def dfv( arg = value):
return arg
Safe exec command: x, y = 1, 2 safeexec ( (x, y, dfv(z=0)), "# do nothing", ( x, y, z) )
(1, 2, 0)
What could we do, not do with this?
* I actually started this reply here, so below is how I got to the
above exression.
I'm trying to put my finger on the basic inconsistency here. It has
something to do with the z=0 as a way to defining a default .
Then there's the lamba which I hear may be removed, but is difficult
to understand for beginners, and isn't readable in that the name
doesn't say what it does. An alternative name, and possibly a
simpler syntax would be a plus.
Another concept that this touches is the indirect execution of an
expression. Exec and eval do that, but then you introduce security
issues.
I'm wondering if there's a fundamental concept under these issues such
as a base function class or command that can evaluate the contents of
a tuple in a secure way?
value = fn(arg, returnvalue)
x = 1 fn( x, x*2)
2
Use lists or tuples for multiple arguments and return expressions:
x, y, z = 1, 2, 3 fn( (x,y,z=0), (x,y,z) )
(1, 2, 3)
But it's that "z=0" causes problems here. In a tuple it's equivalent
to saying 1=2. or 'a'='b'
So we need a way to say 'if name is undefined, bind it to object'.
# function to give a default value
def dfv( arg = value):
return arg
x, y = 1, 2 fn( (x, y, dfv(x=0)), ( x, y, z ))
(1, 2, 3)
Now since this could execute in it's own private space, it might also
offer a way to use exec or eval() indirectly in a very limited and
safe way.
estring = \
"""
result = ''
data = 'abcdefghigklmnop'
for ch in data:
if ch != filterc:
result.join(ch)
""" fn( ( dfv(filterc='d'), evalstring), (exec estring) )
So we need to use a three item tuple:
safe_exec ( (*inputs) , (expressionstring) , ( *outputs) )
def dfv( arg = value):
return arg x, y = 1, 2 safeexec( (x, y, dfv(z=0)), "# do nothing", ( x, y, z) )
(1, 2, 0)
Long way around to here, but is this something that has potential?
It would have to be a built in to ensure it's safe to use. But with
an exec string, it can possibly do a lot more than lamba, and it
probably wouldn't be as fast. But the flexibility could be useful.
Ron
Ron a écrit :
(snip) def dfv( arg = value): return arg def dfv( arg = value):
.... return arg
....
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'value' is not defined
And sorry, but -1 for using exec here.
Ron a écrit : On 21 Mar 2005 22:37:42 -0800, "Kay Schluehr" <ka**********@gmx.net> wrote:
Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
I think that there's too much implied, and that in the long run it, if we keep addding in special shortcuts, it will lead to very dificult to read code.
Don't like Perl ?-)
The problem here is that Kay's proposition mixes two points: flexible
tuple unpacking and a new syntax for anonymous functions.
Diez B. Roggisch a écrit :
(snip) You are right, but for lambda in its current limited form short, named functions are a good replacement.
-inf on this !-)
On Tue, 22 Mar 2005 21:43:48 +0100, Bruno Desthuilliers
<bd*****************@free.quelquepart.fr> wrote: Ron a écrit : (snip)def dfv( arg = value):
return arg
def dfv( arg = value):... return arg ... Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'value' is not defined
And sorry, but -1 for using exec here.
Yes, I cought that myself. So...
try: z=z
except: z=0
or
if 'z' not in locals():
z = 0
Ok, thinking in more incremental terms...
Why should a function not create a local varable of an argument if the
varable doesn't exist and a default value is given?
So when:
Def dfv( v=0):
return v
dfv()
0 ;it creates the local copy in this case.
a = 25 dfv(a)
25 ;It used the given value as expected.
dfv(b)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
dfv(b)
NameError: name 'b' is not defined
Why not let it set the local varable v to the default as it does when
no varable is specified?
A function without a default would still give an error as expected.
:)
Ok no exec, but what about the general syntax?
value = keyword (inputargs, command, outputargs)
I was thinking if it can be done with standard tuples, it has the
potential to be passed around easily and work from lists and
dictionaries.
Ron
On Tue, 22 Mar 2005 21:56:57 GMT, Ron <ra****@tampabay.rr.com> wrote: Why should a function not create a local varable of an argument if the varable doesn't exist and a default value is given?
ok... thought it out better. :)
Getting a default into a function isn't the problem. Returning the
value to a varable that doesn't exist is.
So then the question is ... is there a way for a function to create a
varable in it's parents namespace that persists after the function is
done?
"Ron" <ra****@tampabay.rr.com> wrote: On Tue, 22 Mar 2005 21:56:57 GMT, Ron <ra****@tampabay.rr.com> wrote:
Why should a function not create a local varable of an argument if the varable doesn't exist and a default value is given?
ok... thought it out better. :)
Getting a default into a function isn't the problem. Returning the value to a varable that doesn't exist is.
So then the question is ... is there a way for a function to create a varable in it's parents namespace that persists after the function is done?
Yeap.. a simple one-liner can do the trick:
def makeVars(**nameVals):
sys._getframe(1).f_locals.update(nameVals)
try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"
George
On Tue, 22 Mar 2005 18:15:25 -0500, "George Sakkis"
<gs*****@rutgers.edu> wrote: "Ron" <ra****@tampabay.rr.com> wrote: On Tue, 22 Mar 2005 21:56:57 GMT, Ron <ra****@tampabay.rr.com> wrote:
>Why should a function not create a local varable of an argument if the >varable doesn't exist and a default value is given? Yeap.. a simple one-liner can do the trick:
def makeVars(**nameVals): sys._getframe(1).f_locals.update(nameVals)
try: b except NameError: print "Before makeVars: NameError" else: print "Before makeVars: Not NameError" makeVars(b=2) try: b except NameError: print "After makeVars: NameError" else: print "After makeVars: Not NameError"
George
Cool! Thanks George, so I can do this:
# Set a varable to a default value if it doesn't exist.
# Return the same value back if it does.
# Use: varable = dfvalue( varable=object)
def defvalue(**var):
if var.keys()[0] not in sys._getframe(1).f_locals.keys():
return var.values()[0]
return sys._getframe(1).f_locals[var.keys()[0]]
f = defvalue(f=0)
print f # 0
g = 19
g = defvalue(g=0)
print g # 19
Would there be any problems with using this function?
Not sure where I need it. Was thinking it could be used inside
expressions somehow, and it was an iteresting problem. ;)
Ron
On Tue, 22 Mar 2005 21:45:42 +0100, Bruno Desthuilliers
<bd*****************@free.quelquepart.fr> wrote: Ron a écrit : On 21 Mar 2005 22:37:42 -0800, "Kay Schluehr" <ka**********@gmx.net> wrote:
Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
I think that there's too much implied, and that in the long run it, if we keep addding in special shortcuts, it will lead to very dificult to read code. Don't like Perl ?-)
I tried it.. Wrote a html reformatter in it a long time ago. Wasn't
tempted to do anything else with it. It was good for that, but I went
a month later and had trouble figuring out how it worked. :)
The problem here is that Kay's proposition mixes two points: flexible tuple unpacking and a new syntax for anonymous functions.
Yes, two different problems. I don't think anything needs to be done
to tuples myself. I tend to use lists more anyway.
As far as anonymous functions go... What if there where a container
type to hold unexecuted python code until it is asked to do it. And to
be able to assign it a name, so it would have an object class and
type. But be defined by like a tuple. No addition syntax to make
things confusing. sum = (* a = b+c *)
The (* and *) could be something more appropriate. As long as it's
easy to identify and can't be confused with anything else.
There would be an order of precedence to it also so you could do:
my_button_action = (*a+=c (*if b:c=1 (*if not z: b=False*) *) *)
It would execute from the inside (*_*) outward and use the local name
space it's executed in, so no passing arguments or return values.
Nesting and order of precedence has worked for a long time. to
evaluate it you would need a keyword...
newlamba my_button_action
or this could be valid:newlamba (* a+=c (* if b:c=1 (* if not z:b=False *) *) *)
or left to right order of execution:newlamba (* a = b+c+d, if a>limit:done=True *)
If argument passing is really needed, I suppose there could be an
export/inport method attached to it.
newlamba (* sum = a+b *).import(a,b).export(sum)
ornewlamba (* sum = a+b *).in_out(a,b -> sum)
newlamba my_button_action.in_out(a,b ->sum)
A differnt name would be nice... code, docode, dothis, process... ?
or if you require the in_out method to start it, you don't need the
keyword.
mybutton = (* sum = a+b *) # does not execute, but binds it to a
b = mybutton.in_out(a,b -> sum) # This evaluates first, the sum is bound to b.
b = (* sum = a+b *).in_out(a,b -> sum) # Is the same as above.
Yes, there are probably loads of stuff wrong with this. ;-)
Ron Adam
(Looks like another Ron joined the group.)
Op 2005-03-22, Diez B. Roggisch schreef <de*********@web.de>: Not exactly in fact - unless I messed something. There are 2 problems here: a more flexible tuple unpacking, *and* a lambda in disguise. Actually, I'd go + 1 for the first, -1 for the second
The proposed syntax from Kay is lambda in disguise. To make it work like George want it is modifying the unpacking behaviour. Actually while Kay proposed his syntax as result of the discussion started by George it won't work for that case. The reason is simply that the lambda form returns a tuple, but does not make any revelations about the variable names that tuple shall be unpacked to.
So they are in fact unrelated - at least if introduced as declared. An augmentation to fulfill George's wishes could look like this:
[a,b,c for a,b,c: (x,y,z=0)-> x,y,z) in values]
Yes, one can live without... <troll> ...and without list comprehensions, __call__ and other special methods, descriptors, metaclasses, first class functions, builtin datatypes like lists and dicts, exceptions, dynamic typing, garbage collection, etc too. Hurray, let's all happily program in assembly !-) </troll>
You are right, but for lambda in its current limited form short, named functions are a good replacement. I don't want to get rid of lambda - but since listcomps got introduced, 95% of my usages of them disappeared.
I don't understand why people always say short named functions are a
good replacement. IMO list comprehensions and generator expressions
use lambda's in disguise. When we write something like
[x * x for x in some_iterator], nobody seems to have problems that
we just write an expression here and nobody is argueing that we
should define a short function. However when people need the
same kind of semantics in their function, being an expression that
is being reevaluated with different values, for which lambda is the
natural candidate, suddenly we should use short named functions.
Can someone who thinks this way, please explain why this is acceptable
[ x * x for x in some_iterator ]
But this is not
map(lambda x: x * x, some_iteraror)
and should be replaced with
def sqr(x): return x * x
map(sqr , some_iterator)
--
Antoon Pardon
Ron wrote: On Tue, 22 Mar 2005 21:56:57 GMT, Ron <ra****@tampabay.rr.com> wrote:
Why should a function not create a local varable of an argument if the varable doesn't exist and a default value is given?
ok... thought it out better. :)
Getting a default into a function isn't the problem. Returning the value to a varable that doesn't exist is.
So then the question is ... is there a way for a function to create a varable in it's parents namespace that persists after the function is done?
yes, that'w called a global, and it's UGLY(tm) def yuck():
.... global G
.... G = 42
.... G
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'G' is not defined yuck() G
42
Anyone doing such a thing in my team would be shoot down at once !-)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
George Sakkis wrote: "Ron" <ra****@tampabay.rr.com> wrote:
On Tue, 22 Mar 2005 21:56:57 GMT, Ron <ra****@tampabay.rr.com> wrote:
Why should a function not create a local varable of an argument if the varable doesn't exist and a default value is given?
ok... thought it out better. :)
Getting a default into a function isn't the problem. Returning the value to a varable that doesn't exist is.
So then the question is ... is there a way for a function to create a varable in it's parents namespace that persists after the function is done?
Yeap.. a simple one-liner can do the trick:
def makeVars(**nameVals): sys._getframe(1).f_locals.update(nameVals)
try: b except NameError: print "Before makeVars: NameError" else: print "Before makeVars: Not NameError" makeVars(b=2) try: b except NameError: print "After makeVars: NameError" else: print "After makeVars: Not NameError"
Interesting. I'll keep a copy of this one in my cookbook for further
exploration. But I think I would use such a thing in production code. b = 25 makeVars(b=88) b
88
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Ron wrote: On Tue, 22 Mar 2005 21:45:42 +0100, Bruno Desthuilliers <bd*****************@free.quelquepart.fr> wrote:
Ron a écrit :
On 21 Mar 2005 22:37:42 -0800, "Kay Schluehr" <ka**********@gmx.net> wrote: Mappings like that:
((x,y),z) -> x+y-z
((x,y=0),z) -> None
should be valid actions too.
What is the audience thinking about that?
I think that there's too much implied, and that in the long run it, if we keep addding in special shortcuts, it will lead to very dificult to read code.
Don't like Perl ?-)
I tried it.. Wrote a html reformatter in it a long time ago. Wasn't tempted to do anything else with it. It was good for that, but I went a month later and had trouble figuring out how it worked. :)
This was kind of rethorical question !-) The problem here is that Kay's proposition mixes two points: flexible tuple unpacking and a new syntax for anonymous functions.
Yes, two different problems. I don't think anything needs to be done to tuples myself. I tend to use lists more anyway.
They are two different beasts. Note that you don't have anything like
list unpacking, now tuple unpacking is pretty common in Python (swap,
multiple return values, formatted strings and outputs, ...). As far as anonymous functions go...
(snip prospective code)
Yes, there are probably loads of stuff wrong with this. ;-)
Err... Isn't it a bit more complicated than our actual lambdas ?-)
--
bruno desthuilliers
ruby -e "print 'o****@xiludom.gro'.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"
George Sakkis wrote: So then the question is ... is there a way for a function to create a varable in it's parents namespace that persists after the function is done?
Yeap.. a simple one-liner can do the trick:
def makeVars(**nameVals): sys._getframe(1).f_locals.update(nameVals)
try: b except NameError: print "Before makeVars: NameError" else: print "Before makeVars: Not NameError" makeVars(b=2) try: b except NameError: print "After makeVars: NameError" else: print "After makeVars: Not NameError"
Do I really need to mention that the whole concept here is broken. This
only works if you call it from global scope. If you call it from inside a
function it [usually] won't work: def makeVars(**nameVals):
sys._getframe(1).f_locals.update(nameVals)
def test():
try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"
import sys test()
Before makeVars: NameError
After makeVars: NameError
> Can someone who thinks this way, please explain why this is acceptable [ x * x for x in some_iterator ]
But this is not
map(lambda x: x * x, some_iteraror)
and should be replaced with
def sqr(x): return x * x map(sqr , some_iterator)
It shouldn't, it should be replaced with the listcomp. And IMHO it results
in better readable code.
AFAIK the reason people say you should use named functions is _not_ because
of these single expression replacements. The reason is that frequently
people complain about lambda being so restrictive so that you can't write
lambda x,y: if x > 100: x else: y
and want to _extend_ lambda beyond its current capabilities and make it full
featured but anonymous functions.
And these requests are rebuked with the argument that having to give a more
complex function a name instead of declaring it anonymously doesn't cost
you much - especially since you can declare them inside other functions so
the global namespace isn't cluttered.
I have to admit that rereading my statement
"""
You are right, but for lambda in its current limited form short, named
functions are a good replacement
"""
is not really what I wanted to say.
I should have written:
"""
for lambda in its current limited form, listcomprehensions often are a good
replacement.
"""
But as I've said various times before: I personally don't mind lambdas and
for example the reduce function has been useful for me quite a few times,
can't be replaced by listcomps, and frequently needs a callable consisting
of only a single expression. So I'll continue to use lambdas there.
--
Regards,
Diez B. Roggisch
Duncan Booth wrote: Do I really need to mention that the whole concept here is broken.
This only works if you call it from global scope. If you call it from
inside a function it [usually] won't work:
def makeVars(**nameVals): sys._getframe(1).f_locals.update(nameVals)
def test(): try: b except NameError: print "Before makeVars: NameError" else: print "Before makeVars: Not NameError" makeVars(b=2) try: b except NameError: print "After makeVars: NameError" else: print "After makeVars: Not NameError"
import sys test() Before makeVars: NameError After makeVars: NameError
Yes.
To put it short:
def makeVars(**nameVals):
print "prev",sys._getframe(1).f_locals["z"]
sys._getframe(1).f_locals.update(nameVals)
print "post",sys._getframe(1).f_locals["z"]
def test():
z = 0
makeVars(z=2)
z = 0 makeVars(z=3)
prev 0
post 3
test()
prev 0
post 0
The Python runtime uses the opcodes STORE_FAST and LOAD_FAST to
store/access local variables of a function.
Take a closer look at the code:
case STORE_FAST:
v = POP();
SETLOCAL(oparg, v);
goto fast_next_opcode;
with
register PyObject **fastlocals
and macros
#define GETLOCAL(i) (fastlocals[i])
#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
GETLOCAL(i) = value; \
Py_XDECREF(tmp); } while (0)
The local variables will be stored in the pointer array fastlocals not
within a Python dict.
If a variable is created as a global it will be stored using the
STORE_NAME opcode instead:
case STORE_NAME:
w = GETITEM(names, oparg);
v = POP();
if ((x = f->f_locals) != NULL) {
if (PyDict_CheckExact(x))
err = PyDict_SetItem(x, w, v);
else
err = PyObject_SetItem(x, w, v);
Py_DECREF(v);
if (err == 0) continue;
break;
}
which clearly accesses a Python dict for storage.
Regards Kay
Op 2005-03-23, Diez B. Roggisch schreef <de*********@web.de>: Can someone who thinks this way, please explain why this is acceptable
[ x * x for x in some_iterator ]
But this is not
map(lambda x: x * x, some_iteraror)
and should be replaced with
def sqr(x): return x * x map(sqr , some_iterator) It shouldn't, it should be replaced with the listcomp. And IMHO it results in better readable code.
This misses the point. The fact that map and the listcomprehension do
the same stuff is just a detail. It is about giving a function an
expression as argument that is to be evaluated multiple times.
AFAIK the reason people say you should use named functions is _not_ because of these single expression replacements. The reason is that frequently people complain about lambda being so restrictive so that you can't write
lambda x,y: if x > 100: x else: y
and want to _extend_ lambda beyond its current capabilities and make it full featured but anonymous functions.
This is one kind of people. An other kind of people seems to want to
get rid of lamda's altogether and asks whether it is so difficult
to make a named function each time you would otherwise use a lambda.
But as I've said various times before: I personally don't mind lambdas and for example the reduce function has been useful for me quite a few times, can't be replaced by listcomps, and frequently needs a callable consisting of only a single expression. So I'll continue to use lambdas there.
Then my question was not meant for you.
--
Antoon Pardon
On 23 Mar 2005 10:13:16 GMT, Duncan Booth
<du**********@invalid.invalid> wrote: Do I really need to mention that the whole concept here is broken. This only works if you call it from global scope. If you call it from inside a function it [usually] won't work:
That's only becuase it was asked to go up 1 frame, and not 2.
def makeVars(**nameVals):
sys._getframe(2).f_locals.update(nameVals) # <- get 2 frames up.
def test():
try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"
import sys
test()
Before makeVars: NameError
After makeVars: Not NameError
On 23 Mar 2005 10:13:16 GMT, Duncan Booth
<du**********@invalid.invalid> wrote: Do I really need to mention that the whole concept here is broken. This only works if you call it from global scope. If you call it from inside a function it [usually] won't work:
Ok... you can get globals this way if you know how many frames up it
is. Not terrable useful. :/
def frame0():
print 'frame0 (locals): ',sys._getframe(0).f_locals
print '\nframe1 (parent): ',sys._getframe(1).f_locals
print '\n(Global) : ',sys._getframe(2).f_locals
def frame1():
frame0()
import sys
frame1()
frame0 (locals): {}
frame1 (parent): {}
(Global) : {'__builtins__': <module '__builtin__' (built-in)>, 'sys':
<module 'sys' (built-in)>, '__name__': '__main__', 'frame1': <function
frame1 at 0x00B437B0>, 'frame0': <function frame0 at 0x00B43770>,
'__doc__': None}
Ron wrote: On 23 Mar 2005 10:13:16 GMT, Duncan Booth <du**********@invalid.invalid> wrote:
Do I really need to mention that the whole concept here is broken.
This only works if you call it from global scope. If you call it from
inside a function it [usually] won't work:
That's only becuase it was asked to go up 1 frame, and not 2.
def makeVars(**nameVals): sys._getframe(2).f_locals.update(nameVals) # <- get 2 frames up.
def test(): try: b except NameError: print "Before makeVars: NameError" else: print "Before makeVars: Not NameError" makeVars(b=2) try: b except NameError: print "After makeVars: NameError" else: print "After makeVars: Not NameError"
import sys test()
Before makeVars: NameError After makeVars: Not NameError
That's true only because the globals are updated by {"b":2}
two levels down.
If You nest the test() function You reproduce the error again:
def test():
def inner(): try: b
except NameError: print "Before makeVars: NameError"
else: print "Before makeVars: Not NameError"
makeVars(b=2)
try: b
except NameError: print "After makeVars: NameError"
else: print "After makeVars: Not NameError"
inner()
Before makeVars: NameError
After makeVars: NameError
A working makeVars seems not to be different from
def makeVars(**nameVals):
globals().update(nameVals)
Regards Kay
Kay Schluehr wrote: A working makeVars seems not to be different from
def makeVars(**nameVals): globals().update(nameVals)
Not quite. If Ron can come up with a working makeVars it would update the
caller's globals whereas what you just posted updates makeVar's globals so
there is a difference (when the makeVars and the calling function are in
different modules), just not a very useful one.
On 23 Mar 2005 08:31:36 GMT
Antoon Pardon <ap*****@forel.vub.ac.be> wrote: Can someone who thinks this way, please explain why this is acceptable
[ x * x for x in some_iterator ]
But this is not
map(lambda x: x * x, some_iteraror)
and should be replaced with
def sqr(x): return x * x map(sqr , some_iterator)
I guess I have similar feelings.
I've only been using python for a year or two, so I'm still a relative
newcomer.
Like a lot of people, I found Python to be magically simple and intuitive.
But I've never really found list comprehensions particularly clear. I don't
know whether it's my backgroud (mainly C/C++), or my brain or what, but they
are probably the only thing in Python that hasn't seemed transparent and
obvious to me (apart from shadowing of variables in nested functions).
Of course, I'm sure I could get used to them, given time. But that rather
defeats one of the main reasons for using python in the first place - the
lack of a steep learning curve.
In contrast, I find lambdas, even with their significant restrictions, to be
much more obvious. In fact, the proposal (sorry, don't have a link to hand)
about extending lambda to allow things like `myfn = def <indented block>' was
something that I initially assumed would become part of the language in time.
Is there some definitive information that explains why python is moving away
from lambdas and towards things like list comprehensions?
- Julian
-- http://www.op59.net/
"bruno modulix" <on***@xiludom.gro> wrote: in message news:42**********************@news.free.fr... Ron wrote:The problem here is that Kay's proposition mixes two points: flexible tuple unpacking and a new syntax for anonymous functions.
Yes, two different problems. I don't think anything needs to be done to tuples myself. I tend to use lists more anyway.
They are two different beasts. Note that you don't have anything like list unpacking, now tuple unpacking is pretty common in Python (swap, multiple return values, formatted strings and outputs, ...).
All the following are possible: (x,y,z) = (1,2,3) (x,y,z) = [1,2,3] [x,y,z] = (1,2,3) [x,y,z] = [1,2,3]
What exactly do you mean by "don't have anything like list unpacking" ?
George
On 23 Mar 2005 14:47:30 GMT, Duncan Booth
<du**********@invalid.invalid> wrote: Kay Schluehr wrote:
A working makeVars seems not to be different from
def makeVars(**nameVals): globals().update(nameVals)
Not quite. If Ron can come up with a working makeVars it would update the caller's globals whereas what you just posted updates makeVar's globals so there is a difference (when the makeVars and the calling function are in different modules), just not a very useful one.
How about this one? The only reliable way I found to do it is to
pass locals() to the function.
def defvalue(**args):
args = args.items()
a1 = args[0]
a2 = args[1]
if type(a1[1]) == type({}):
vv, names = a2, a1[1]
else:
vv, names = a1, a2[1]
if names.has_key(vv[0]):
return names[vv[0]]
return vv[1]
f = defvalue(f=1, v=locals())
print f # 0
g = 19
g = defvalue(g=2, v=locals())
print g # 19
z = 6
def f1():
#z = 4
z = defvalue(z=3, v=locals())
print z
f1()
George Sakkis wrote: "bruno modulix" <on***@xiludom.gro> wrote: in message news:42**********************@news.free.fr...
(snip) Note that you don't have anything like list unpacking, now tuple unpacking is pretty common in Python (swap, multiple return values, formatted strings and outputs, ...).
All the following are possible:
(x,y,z) = (1,2,3) (x,y,z) = [1,2,3] [x,y,z] = (1,2,3) [x,y,z] = [1,2,3]
What exactly do you mean by "don't have anything like list unpacking" ?
A stupidity :(
--
bruno desthuilliers
ruby -e "print 'on***@xiludom.gro'.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"
Ron wrote: A working makeVars seems not to be different from
def makeVars(**nameVals): globals().update(nameVals)
Not quite. If Ron can come up with a working makeVars it would update the caller's globals whereas what you just posted updates makeVar's globals so there is a difference (when the makeVars and the calling function are in different modules), just not a very useful one.
How about this one? The only reliable way I found to do it is to pass locals() to the function.
Yes, but you are still missing the fundamental point. The locals()
dictionary is not guaranteed to do anything useful if you update it. The
current C implementation will reflect changes in the locals dictionary if
you call locals() from global scope or in a few other circumstances, but
this is simply an implementation detail.
If you want to update global variables then use globals() or setattr on the
module. Only use locals() to access local variables indirectly, never to
try and set them.
On 24 Mar 2005 09:20:52 GMT, Duncan Booth
<du**********@invalid.invalid> wrote: Ron wrote:
A working makeVars seems not to be different from
def makeVars(**nameVals): globals().update(nameVals)
Not quite. If Ron can come up with a working makeVars it would update the caller's globals whereas what you just posted updates makeVar's globals so there is a difference (when the makeVars and the calling function are in different modules), just not a very useful one. How about this one? The only reliable way I found to do it is to pass locals() to the function.
Yes, but you are still missing the fundamental point. The locals() dictionary is not guaranteed to do anything useful if you update it. The current C implementation will reflect changes in the locals dictionary if you call locals() from global scope or in a few other circumstances, but this is simply an implementation detail.
Nope, Didn't miss the point. The functions return a value, not create
it from within.
If you want to update global variables then use globals() or setattr on the module. Only use locals() to access local variables indirectly, never to try and set them.
Good advise. :)
One of pythons weak points is it is sometimes difficult to 'monitor
and confirm' what is happening leading to confusing try/except
constructions.
Having the function is_defined() and if_not_defined() have the
advantage that they can be use in expressions where try/except can't.
And the source code could be more compact and more readable.
The disadvantage is the functions are quite a bit slower than
try/except, probably due to the function call over head.
If they were built in, they may be as fast as the try/except and there
wouldn't be issues with having to passing locals() or globals() name
dictionaries.
It's interesting that there is a whole is_"type"_() group of functions
in the inspect module, but not a is_defined(). Maybe I just haven't
found it yet.
#############
def if_not_defined(v, dv=None, lv=locals()):
if lv.has_key(v):
return lv[v]
return dv
def is_defined(v, lv=locals()):
if lv.has_key(v):
return True
False
# Shorten names and pass locals() with lambas for
# convenience. (This needs to be in the function
# where they are used or it will break.
# Another use for lamba! ;)
ifnd = lambda v, dv, lv=locals(): if_not_defined(v,dv,lv)
isa = lambda v, lv=locals(): is_defined(v, lv)
# Totally useless routine. ;)
import random
for n in range(10):
# Delete a random x,y,z coordinate to
# simulate an unreliable data source.
d = random.choice([1,2,3])
if d==1:
if isa('x'): del x
elif d==2:
if isa('y'): del y
else:
if isa('z'): del z
# Replace the missing variable with a random number.
r = int(random.random()*100)
x, y, z = ifnd('x',r), ifnd('y',r), ifnd('z',r)
print x, y, z
###########
Ron wrote: It's interesting that there is a whole is_"type"_() group of functions in the inspect module, but not a is_defined(). Maybe I just haven't found it yet.
I've never found any need for an is_defined function. If in doubt I just
make sure and initialise all variables to a suitable value before use.
However, I'll assume you have a good use case.
#############
def if_not_defined(v, dv=None, lv=locals()): if lv.has_key(v): return lv[v] return dv
I don't see the point of the default argument. locals() at the global level
simply returns globals, so you might as well use that. A more useful
default would be the caller's locals. def is_defined(v, lv=locals()): if lv.has_key(v): return True False
Same comments, plus the whole 'if on a boolean to return a boolean' is a
bit redundant.
Try something on these lines: import inspect def is_defined(name, lv=None):
if lv is None:
lv = inspect.currentframe().f_back.f_locals
return name in lv
is_defined('abc')
False abc = 3 is_defined('abc')
True def f(x):
print is_defined('x')
print is_defined('y')
y = 0
print is_defined('y')
f(2)
True
False
True # Shorten names and pass locals() with lambas for # convenience. (This needs to be in the function # where they are used or it will break. # Another use for lamba! ;)
ifnd = lambda v, dv, lv=locals(): if_not_defined(v,dv,lv) isa = lambda v, lv=locals(): is_defined(v, lv)
There is no need for lambda here, it adds nothing. Use a 'def'.
On 25 Mar 2005 10:09:50 GMT, Duncan Booth
<du**********@invalid.invalid> wrote: I've never found any need for an is_defined function. If in doubt I just make sure and initialise all variables to a suitable value before use. However, I'll assume you have a good use case.
I admit that that is the better practice. George's example was the
conversion of data from one form to another where the data is mixed
with complete and incomplete items. And Kay is looking at tuple
unpacking.
It's hard to beat try/except for these situations though. :)
I cleaned it up some more and figured out the proper use of
_getframe(). So no lambdas, and no passing of locals needed., and it
checks for globals and builtins before defining the default value so
as not to over write a readable value.
I'm not sure what the best behavior should be. Maybe a routine to
tell where a name is, ie.. local, global, builtin, or a writable
global? maybe isa() return the location or None.? I think that would
be better.
The best purpose for utilities like these is for debugging and getting
feedback about the environment. So I'm thinking of putting them in a
module for that purpose. I have a subroutine to list all the names
attached to an object. I think I can add that a bit now too.
#---Here's the code---------------------
import sys
def isa(v):
"""
Check if a varable exists in the current
(parent to this function), global, or
builtin name spaces.
use: bool = isa( str )
returns True or False
"""
plocals = sys._getframe(1).f_locals
if plocals.has_key(v) or globals().has_key(v) or \
__builtins__.locals().has_key(v):
return True
return False
def ifno(v, obj=None):
"""
Check if a varable does not exists, return a
default value, otherwise return the varable obj.
use: obj = ifno( str [,obj=None] )
if str exist, returns str's object
if str does not exist, returns specified object
"""
plocals = sys._getframe(1).f_locals
if plocals.has_key(v):
return plocals[v]
if globals().has_key(v):
return globals()[v]
if __builtins__.locals().has_key(v):
return __builtins__.locals()[v]
return obj
def test():
"""
Test isa() and ifno() functions:
"""
# Totally useless routine. ;)
import random
for n in range(25):
# Delete a random x,y,z coordinate to
# simulate an unrealiabe data source.
d = random.choice([1,2,3])
if d==1:
if isa('x'): del x
elif d==2:
if isa('y'): del y
else:
if isa('z'): del z
# Replace the missing Varible with a random number.
r = int(random.random()*100)
x, y, z = ifno('x',r), ifno('y',r), ifno('z',r)
print x, y, z
if __name__ == '__main__':
test()
#-------------------------------------
"Ron_Adam" <ra****@tampabay.rr.com> wrote: On 25 Mar 2005 10:09:50 GMT, Duncan Booth <du**********@invalid.invalid> wrote:
I've never found any need for an is_defined function. If in doubt I just make sure and initialise all variables to a suitable value before use. However, I'll assume you have a good use case.
I admit that that is the better practice. George's example was the conversion of data from one form to another where the data is mixed with complete and incomplete items. And Kay is looking at tuple unpacking.
It's hard to beat try/except for these situations though. :)
I posted a recipe in python cookbook
( http://aspn.activestate.com/ASPN/Coo.../Recipe/392768) for the subproblem I was interested
in initially (variable-length iterable unpacking), and I prefer it over explicit try/except (but of
course I'm biased :-)). Kay is proposing something even more general and powerful, and it will be
interesting to see if all this brainstorming can be brought forward more 'formally', e.g. at a PEP
or pre-PEP level.
Regards,
George
On Fri, 25 Mar 2005 17:09:38 -0500, "George Sakkis"
<gs*****@rutgers.edu> wrote: I posted a recipe in python cookbook (http://aspn.activestate.com/ASPN/Coo.../Recipe/392768) for the subproblem I was interested in initially (variable-length iterable unpacking), and I prefer it over explicit try/except (but of course I'm biased :-)). Kay is proposing something even more general and powerful, and it will be interesting to see if all this brainstorming can be brought forward more 'formally', e.g. at a PEP or pre-PEP level.
Regards, George
Looks good George. :)
I'm not sure what Kay is trying for, but it does look interesting. I'm
all for new features as long as they are consistent and easy to use,
and easy to remember as well. I keep finding ways to improve the
little routines I'm playing with. ;) I'll probably post them in the
cookbook also, and maybe put them together in a mod.
A few more pieces and I should be able to build a name space explorer
which I think will be good for debugging programs. I'm thinking you
could put it in the program where you are having problems and it will
open a tree type window where you can examine all the names and
objects at that point. When done, close it and the programs
continues. It will give you a little more info than sticking print
statements hear and there.
Ron This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Jim Newton |
last post by:
hi all, i'm relatively new to python. I find it a
pretty interesting language but also somewhat limiting
compared to lisp. I notice that the language does
provide a few lispy type nicities, but...
|
by: Kay Schluehr |
last post by:
Since George Sakkis proposed a new way of doing list comprehensions
http://groups-beta.google.com/group/comp.lang.python/browse_frm/thread/ac5023ad18b2835f/d3ff1b81fa70c8a7#d3ff1b81fa70c8a7
...
|
by: Kay Schluehr |
last post by:
Hi all,
thanks for Your attention !
I think my proposal was more in mind of Rons modified exec than
Pythons lambda.
When George proposed his unpacking behavoir for list-comps as a pack of...
|
by: sandman |
last post by:
I've been testing my web app on another workstation to simulate using
the server time. The test pc's time is an hour behind the server time
and when the user processes a request, the server time...
|
by: Steeve |
last post by:
Hi,
I found a way to get result than I want with this anonymus method. But,
it's a little weird to use a anonymus methods in another anonymus
methods. Moreover, i have a performance issue. How...
|
by: James Kanze |
last post by:
Just ran into an interesting question concerning SFINAE. Given
the following code:
#include <iostream>
#include <typeinfo>
template< typename T >
class P
{
public:
|
by: Immortal Nephi |
last post by:
My project grows large when I put too many member functions into one
class. The header file and source code file will have approximately
50,000 lines when one class contains thousand member...
|
by: Rich Fife |
last post by:
Quick rand() question:
I know you're not supposed to use "rand() % 1024" for instance,
because it focuses on the lower bits. However, it seems to me that
given that the argument is not a power...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
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...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
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...
|
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...
|
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,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |