ASPN ActiveState Programmer Network  
ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: Assignment in expression
Submitter: Sébastien Keim (other recipes)
Last Updated: 2003/05/26
Version no: 1.1
Category: Shortcuts

 

5 stars 7 vote(s)


Description:

An evil equivalent for C expression: 'while x=f()'.

Source: Text Source

import sys
def set(**kw):
    assert len(kw)==1
    
    a = sys._getframe(1)
    a.f_locals.update(kw)
    return kw.values()[0]

#
# sample
#

A=range(10)

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

Discussion:

This recipe is an abuse of implementation details which should only be used by debugging tools. So I strongly advise you to not use it in production code.

But it's quite fun and can still be useful for bets.



Add comment

Number of comments: 11

an alternative using list comprehensions, Andrew Dalke, 2003/07/29
Again, don't use this in real code.

>>> a = [1, 2, 9, 0]
>>> n = iter(a).next
>>> while [x for x in [n()] if x]:
... 	print "I have", x
... 
I have 1
I have 2
I have 9
>>> 

Add comment

won't work in future versions, Yair Chuchem, 2005/08/08
In future versions of python - list comprehensions won't expose the inner variable.
Add comment

Very nice., Raymond Hettinger, 2005/05/25

Add comment

Alternative, safer methods, Frank P Mora, 2005/06/22

Assignment statements and statements in general are anathema to
purely functional language and Lisp programmers but are sometimes
but rarely required. Assignment in an expression can also be achieved
like this: >>> ## Directly with the expressly designed function: >>> import __main__ >>> setattr(__main__,'aaa', 300) >>> aaa 300 >>> ## Or again with the update method and dictionaries >>> locals().update({'aaa2':200}) >>> aaa2 200 >>> globals().update({'aaa4':500}) >>> aaa4 500 >>> __main__.__dict__.update({'aaa5':600}) >>> aaa5 600 >>> ## Or with the update method and a list of 2-tuples >>> t= ('bbb',6) >>> locals().update([t]) >>> bbb 6 >>> ## Or many at once >>> k= "v1 v2 v3 v4 v5" >>> v= "red blu grn yel brn" >>> locals().update(zip( *[ l.split() for l in (k,v)] )) >>> fmt= "The 5 color codes are %s, %s, %s, %s and %s" >>> print fmt % (v1,v2,v3,v4,v5) The 5 color codes are red, blu, grn, yel and brn Additionally, Dr. David Mertz’s article at http://gnosis.cx/publish/programming/charming_python_19.html addresses “Expression Binding” and the Xoltar functional toolkit.
He offers the following: >>> list_of_list = [[1,2,3],[4,5,6],[7,8,9]] >>> [car_x for x in list_of_list for car_x in (x[0],)] [1, 4, 7] >>> car_x 7

Add comment

An alternative necessary function definition and example, Frank P Mora, 2005/07/04

Sébastien is offering the utility and conciseness of the valued C code
assignment and *not just* expression assignment as in the preceding
comment of mine. His utility is of much greater value. It requires a
function definition by necessity. Here is an alternate function
definition and yet another example of the usefulness of Sébastien’s
idea in a compression that calculates factorials. def sv(vnm='', vval=None, obj=__main__): setattr(obj, vnm, vval) return vval >>> import __main__ >>> fac =4 >>> [ [ sv('j', j*i) for i in range(2,fac+1) ][-1] for j in (1,) ][0] 24 >>> fac=5 >>> [ [ sv('j', j*i) for i in range(2,fac+1) ][-1] for j in (1,) ][0] 120 The advantage of the setattr function is the variable variable which
allows many assignments is a single pass as in the preceding comment.
It is also the standard method of expression assignment in Python.

Add comment

But then again, Frank P Mora, 2005/07/08

The list comprehension can set an initial value as in the latter
part of the factorial comprehension in my last comment. After being
set to 1, ‘j’ then becomes the accumulator in the calculation. If a
list comprehension can set and return values as in a function can they
act as accumulators? It is completly natural for them to do so. >>> fac =6 >>> [ [ [ j for j in (j*i,) ][0] for i in range(2,fac+1) ][-1] for j in (1,) ] [720] Wow! Andrew Dalke and David Mertz are my new hero’s. It
seems like the awe inspiring list comprehension can do just about
anything. Does Python need function definitions at all much less lambdas? Maybe just for readability.

Add comment

Better yet, Frank P Mora, 2005/07/15
Steven Bethard pointed out in recipe 436482 that


[j for j in [1] for i in range(2,fac+1) for j in [j*i]]  [-1]

is equivalent but easier to write, read and use.

Add comment

Perlishly elegant, Connelly Barnes, 2005/10/24

Add comment

set() is now a builtin, Moe Aboulkheir, 2006/02/16
so naming this function "set" is probably not the best idea
Add comment

Brittle solution, Moe Aboulkheir, 2006/03/17
this won't work if you use set() anywhere but the toplevel. e.g:

def myfunc():
  seq = range(10)
  while set(var=seq.pop()):
    print var
myfunc()
-> NameError: global name 'var' is not defined
the behaviour is also different if the loop variable is already bound:
def myfunc(var='x')
  seq = range(10)
  while set(var=seq.pop()):
    print var
myfunc()
-> equivalent to "while seq.pop(): print 'x'"
Add comment

Another solution., Aristotelis Mikropoulos, 2006/08/14
class DataHolder( object ) : """A simple data holder. """ def __init__( Self , Value = None ) : """The constructor. """ Self.Value = Value def Get( Self ) : """Returns the value. """ return Self.Value def Set( Self , Value ) : """Sets the value, as well as returns it. """ Self.Value = Value return Self.Value
Add comment



Highest rated recipes:

1. A simple XML-RPC server

2. Web service accessible ...

3. Treat the Win32 Registry ...

4. Watching a directory ...

5. Union Find data structure

6. Function Decorators by ...

7. MS SQL Server log monitor

8. Table objects with ...

9. wx twisted support using ...

10. More accurate sum




Privacy Policy | Email Opt-out | Feedback | Syndication
© 2006 ActiveState Software Inc. All rights reserved.