[Python-Dev] [rfc] map enhancement

Ludovic Aubry Ludovic.Aubry@logilab.fr
Tue, 18 Feb 2003 12:18:44 +0100


First a brief introduction, since this is my first post to python-dev:
I'm a software engineer, mostly using C/C++ and Python. I also
occasionaly teach a tutorial class on Python.

A couple weeks ago I told Raymond Hettinger how I liked itertools
and that I always missed a feature from map that could be easily
implemeted in imap. He told me that he was trying to stay as close
as possible to the behavior of the original map function.

This why I am proposing this backward compatible enhancement to map:

Using map you always end up using lambda functions to pass constant
arguments to the mapping function like this:

map( lambda x,y=K: f(x,y), L )

What I propose in this patch is to have map recognize its keyword
arguments like this:

map( f, L , y=K )

The result would be:
def map( f, L, **kw ): # accepts only one list for simplicity
   for i in L:
      l.append( f(i,**kw) )
   return l

While it doesn't solve every problem (passing a value to the first arg)
it could help remove many uses of lambda functions.

If it turns out to be useful to people other than me I can also make a
patch for the filter function which could benefit from the same

Since the patch is very small I include it here (against the latest
python 2.3 cvs)

Comments ?

Index: src/Doc/lib/libfuncs.tex
RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v
retrieving revision 1.128
diff -u -r1.128 libfuncs.tex
--- src/Doc/lib/libfuncs.tex	31 Jan 2003 17:19:05 -0000	1.128
+++ src/Doc/lib/libfuncs.tex	18 Feb 2003 10:48:15 -0000
@@ -643,12 +643,14 @@
   point numbers to integers truncates (towards zero).
-\begin{funcdesc}{map}{function, list, ...}
+\begin{funcdesc}{map}{function, list1, ..., listN\optional{, k1=a1,...}}
   Apply \var{function} to every item of \var{list} and return a list
   of the results.  If additional \var{list} arguments are passed,
   \var{function} must take that many arguments and is applied to the
   items of all lists in parallel; if a list is shorter than another it
-  is assumed to be extended with \code{None} items.  If \var{function}
+  is assumed to be extended with \code{None} items.  If optional keyword
+  arguments are passed, \var{function} must accept them as named arguments
+  and they are passed each time \var{function} is called.  If \var{function}
   is \code{None}, the identity function is assumed; if there are
   multiple list arguments, \function{map()} returns a list consisting
   of tuples containing the corresponding items from all lists (a kind
Index: src/Python/bltinmodule.c
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.281
diff -u -r2.281 bltinmodule.c
--- src/Python/bltinmodule.c	13 Feb 2003 22:07:58 -0000	2.281
+++ src/Python/bltinmodule.c	18 Feb 2003 10:48:22 -0000
@@ -731,7 +731,7 @@
 static PyObject *
-builtin_map(PyObject *self, PyObject *args)
+builtin_map(PyObject *self, PyObject *args, PyObject *kwargs)
 	typedef struct {
 		PyObject *it;	/* the iterator object */
@@ -854,7 +854,7 @@
 		if (func == Py_None)
 			value = alist;
 		else {
-			value = PyEval_CallObject(func, alist);
+			value = PyEval_CallObjectWithKeywords(func, alist, kwargs);
 			if (value == NULL)
 				goto Fail_1;
@@ -1780,7 +1780,7 @@
  	{"iter",	builtin_iter,       METH_VARARGS, iter_doc},
  	{"len",		builtin_len,        METH_O, len_doc},
  	{"locals",	(PyCFunction)builtin_locals,     METH_NOARGS, locals_doc},
- 	{"map",		builtin_map,        METH_VARARGS, map_doc},
+ 	{"map",		builtin_map,        METH_KEYWORDS, map_doc},
  	{"max",		builtin_max,        METH_VARARGS, max_doc},
  	{"min",		builtin_min,        METH_VARARGS, min_doc},
  	{"oct",		builtin_oct,        METH_O, oct_doc},

Ludovic Aubry                                 LOGILAB, Paris (France).
http://www.logilab.com   http://www.logilab.fr  http://www.logilab.org