473,386 Members | 1,694 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,386 software developers and data experts.

Black Magic - Currying using __get__

Wow - Alex Martelli's 'Black Magic' Pycon notes
http://www.python.org/pycon/2005/pap...c05_bla_dp.pdf

include this gem:
Functions 'r descriptors
def adder(x, y): return x + y
add23 = adder.__get__(23)
add42 = adder.__get__(42)
print add23(100), add42(1000)
123 1042


This means that you can do (left) currying without a separate curry function
(Of course, google reveals that the idea has been discussed before,
http://mail.python.org/pipermail/pyt...er/038933.html)
Although it's less flexible than a general curry function, 'method currying' is
much faster, e.g., compare two functions for tail-filtering an iterator:

def filtertail(op, iterable):
"""Recursively filter the tail of an iterator, based on its head
Useful for succinct (though not very fast) implementations
of sieve of eratosthenes among other"""
iterator = iter(iterable)
while 1:
head = iterator.next()
yield head
iterator = it.ifilter(curry(op,Missing,head), iterator)

def filtertail2(op, iterable):
"""An alternative to filtertail, using Alex Martelli's observation
that functions are descriptors. Will not work for built-in
functions that lack a __get__ method"""
iterator = iter(iterable)
opcurry = op.__get__
while 1:
head = iterator.next()
yield head
iterator = it.ifilter(opcurry(head), iterator)

using these generator functions, a Sieve of Eratosthenes can be written as:

primes = list(filtertail(operator.mod, xrange(2,N)))
or
primes = list(filtertail2(lambda head, tail: tail % head, xrange(2,N)))

but the second version, using 'method currying' is 4 times the speed, despite
not using the stdlib operator.mod function

def timethem(N):
import time
t1 = time.clock()
p = list(filtertail(op.mod, xrange(2,N)))
t2 = time.clock()
p = list(filtertail2(lambda head, tail: tail % head, xrange(2,N)))
t3 = time.clock()
return t2-t1, t3-t2
timethem(10000) (3.8331997502475588, 0.79605759949936328) timethem(100000) (240.68151008019186, 61.818026872130304)


of course, neither version is anywhere near the most efficient Python
implementation - this is a comparison of currying, not sieving.
BTW, here's the curry function I used (it could probably be faster; I'm not sure
what/where the future stdlib version is)
Missing = Ellipsis
def curry(*cargs, **ckwargs):
fn, cargs = cargs[0], cargs[1:]
if cargs[0] is Missing:
while cargs[0] is Missing: # rightcurry
cargs = cargs[1:]
def call_fn(*fargs, **fkwargs):
d = ckwargs.copy()
d.update(fkwargs)
return fn(*(fargs+cargs),**d)
name = "%s(...,%s)" % (fn.__name__, ",".join(repr(i) for i in cargs))
else:
def call_fn(*fargs, **fkwargs):
d = ckwargs.copy()
d.update(fkwargs)
return fn(*(cargs + fargs), **d)
name = "%s(%s,...)" % (fn.__name__, ",".join(repr(i) for i in cargs))
call_fn.func_name = name
call_fn.curry = True
return call_fn

Michael

Jul 18 '05 #1
0 1711

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

Similar topics

8
by: Rico Huijbers | last post by:
Hello, I'd like to know if it's possible to curry a function in PHP? That is, is there some built-in mechanism for it, or is it possible to create a function that does the currying? I've...
2
by: Shalabh Chaturvedi | last post by:
Almost everwhere the descriptor protocol is mentioned, it specifies __get__(obj, typ=None). Why is a default value needed for the second argument? In which case does Python call a descriptor...
5
by: Kenneth McDonald | last post by:
Now that I'm back to Python and all the new (to me) cool features, I find I'm using properties a lot, i.e. I'm defining: foo = property(fset=..., fget=...) for a number of properties, in many...
9
by: Lenard Lindstrom | last post by:
I was wondering if anyone has suggested having Python determine a method's kind from its first parameter. 'self' is a de facto reserved word; 'cls' is a good indicator of a class method ( __new__...
2
by: Jan Burgy | last post by:
Hi everyone, I am trying to convince my managers that python can replace the outdated and soon no-longer maintained proprietary system (Tool for Calculator Design) we use here. In order to...
0
by: John Perks and Sarah Mount | last post by:
I'm talk from the point of view of descriptors. Consider a.x = lambda self:None # simple function When a.x is later got, what criterion is used to see if a class (and so the func would have...
19
by: youpak2000 | last post by:
Are MAGIC numbers always bad? Using magic numbers (constant numbers) in programs are generally considered a bad programming practice, and it's recommended that to define constants in single,...
16
by: per9000 | last post by:
Hi, I recently started working a lot more in python than I have done in the past. And I discovered something that totally removed the pretty pink clouds of beautifulness that had surrounded my...
1
by: robert2821 | last post by:
Hi, I'm new; greetings all! I'm wondering if the following program should work. I think it should print 'Hello, World', but instead it produces a TypeError. Is this a bug in decorators, a...
0
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,...
0
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$) { } ...
0
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...
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
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
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
jinu1996
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...

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.