[Python-ideas] A mutable alternative to namedtuple

Andrew Barnert abarnert at yahoo.com
Thu Mar 19 09:37:26 CET 2015


On Mar 19, 2015, at 12:04 AM, Zaur Shibzukhov <szport at gmail.com> wrote:
> 
> 
> 
> вторник, 17 марта 2015 г., 20:21:01 UTC+3 пользователь Eric V. Smith написал:
>> 
>> On 03/17/2015 12:52 PM, Luciano Ramalho wrote: 
>> > Sometimes we need a simple class to hold some mutable attributes, 
>> > provide a nice repr, support == for testing, and support iterable 
>> > unpacking, so you can write: 
>> > 
>> >>>> p = Point(3, 4) 
>> >>>> x, y = p 
>> > 
>> > That's very much like the classes built by namedtuple, but mutable. 
>> 
>> https://pypi.python.org/pypi/namedlist 
>> 
>> It also adds default values to the generated constructor, which may or 
>> may not be desirable. But if used exactly like collections.namedtuple, 
>> it ignores the default values. 
>> 
>> Eric.
> Since named tuple is considered as an object that is a tuple with attribute access. 
> The mutable alternative could be considered as an array with attribute access.
> Array in this context is tuple-like object that support assign operation.
> Since python have not such object there are different approaches tomutable  named tuple alternatives.

Python definitely does have such an object: list. A list is effectively the same as a tuple but mutable; it's the paradigm MutableSequence while tuple is the paradigm Sequence. Under the covers they have very similar headers that both use the same storage (a C array of pointers to Python objects, in CPython), and C API functions like PySequence_Fast_GET_ITEM don't distinguish between the two.

However, list is resizable, and presumably a "namedlist" would not be. That makes things more complicated for both the interface (there's no is-a relationship; a type without append is not a list--and, worse, a type that has __setitem__ but can't handle slice replacement is not a list but that's very hard to detect...) and the implementation (e.g., a list reserves extra space at the end to avoid having to reallocate on every append). 

(Python _also_ has an array type, which is for homogenous simple types (like 32-bit int) which can store the values directly, as opposed to tuple and list, which store (pointers to) heterogenous normal Python objects.)

> One should note that particular property of named tuple is memory saving.
> So one can expect similar property of mutable named tuple too.

If you don't need to access the items by index for whatever reason, you don't need a namedtuple, and using one as a misguided misoptimization is a bad idea.

Besides the fact that a normal class with __slots__ is also small, and even a normal class with a dict (in newer CPython versions and PyPy) not that much bigger, besides the fact that you can eliminate the row overhead rather than just slightly reducing it by using, e.g., a 2D array, you're optimizing the wrong thing in the first place--if your rows have 9 elements, reducing the row overhead is focusing on fixing 10% of your overhead, while reducing or eliminating the element overhead by using, e.g., a 2D numpy array of low-level values fixes the 90% (along with the 10%).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150319/64005f38/attachment.html>


More information about the Python-ideas mailing list