Named tuples and projection

Giuseppe Ottaviano giuott at
Fri Jun 20 10:38:37 CEST 2008

I found the namedtuple very convenient for rapid prototyping code, for  
functions that have to return a number of results that could grow as  
the code evolves. They are more elegant than dicts, and I don't have  
to create a new explicit class. Unfortunately in this situation they  
lose the convenience of tuple unpacking: changing tuple's parameters  
would break other functions unpacking the result.
One solution, with 3.0 syntax, would be unpacking only the used  
parameters, using always a *rest
a, b, *rest = f()
so that if the tuple grows, the code keeps working.
However I find this confusing (and not avaliable in python 2.5).
I don't know if similar solutions have been proposed, I came up with  
this one:

Add a method "project" that given a string of arguments (in a similar  
fashion as namedtuple construction) returns a tuple with only that  
items. I monkeypatched the namedtuple recipe as a proof of concept,  
replace "return result" with these lines:

     def _project(self, fields):
	return tuple(getattr(self, field) for field in fields.split())
     def _getitem(self, item):
	if isinstance(item, str):
	    return self.project(item)
	return super(result, self).__getitem__(item)

     result.project = _project
     result.__getitem__ = _getitem

     return result

This is the result:

In [2]: X = namedtuple('X', 'a b c d')

In [3]: x = X(1, 2, 3, 4)

In [4]: a, c = x.project('a c')

In [5]: a, c
Out[5]: (1, 3)

In [6]: a, d = x['a d']

In [7]: a, d
Out[7]: (1, 4)

In [8]: x[2]
Out[8]: 3

I implemented also __getitem__ just to show another possible syntax  
(maybe a bit ugly). project may be not a self-evident name, probably  
something like "select" (for SQL addicts) would be more appropriate.
Other possible solutions?


More information about the Python-list mailing list