Differences creating tuples and collections.namedtuples

Oscar Benjamin oscar.j.benjamin at gmail.com
Mon Feb 18 07:03:14 EST 2013


On 18 February 2013 11:47, John Reid <johnbaronreid at gmail.com> wrote:
> Hi,
>
> I was hoping namedtuples could be used as replacements for tuples in all instances.

namedtuples are not really intended to serves as tuples anywhere. They
are intended to provide lightweight, immutable, hashable objects with
*named* (rather than numbered) values.

> There seem to be some differences between how tuples and namedtuples are created. For example with a tuple I can do:
>
> a=tuple([1,2,3])
>
> with namedtuples I get a TypeError:
>
> from collections import namedtuple
> B=namedtuple('B', 'x y z')
> b=B([1,2,3])

For a namedtuple you need to unpack the arguments

b = B(*[1, 2, 3])

or

b = B(1, 2, 3)

>
> TypeError: __new__() takes exactly 4 arguments (2 given)
>> <ipython-input-23-d1da2ef851fb>(3)<module>()
>       1 from collections import namedtuple
>       2 B=namedtuple('B', 'x y z')
> ----> 3 b=B([1,2,3])
>
> I'm seeing this problem because of the following code in IPython:
>
> def canSequence(obj):
>     if isinstance(obj, (list, tuple)):
>         t = type(obj)
>         return t([can(i) for i in obj])
>     else:
>         return obj

What is the point of the code above? If obj is a list or a tuple you
create a new list or tuple with the same data and then return it
otherwise you just return the object. What about:

def canSequence(obj):
    return obj

Or is it that you want to copy the object (but only when it is a tuple
or list). Then how about

def canSequence(obj):
    if isinstance(obj, (list, tuple)):
        return obj[:]
    else:
        return obj

Note that this turns namedtuples into tuples. It might be better to
catch TypeError rather than special casing the types:

def canSequence(obj):
    try:
        return obj[:]
    except TypeError:
        return obj

Or perhaps it would be better to use the copy module (assuming that
the purpose is to copy the object).

>
> where obj is a namedtuple and t([can(i) for i in obj]) fails with the TypeError. See http://article.gmane.org/gmane.comp.python.ipython.user/10270 for more info.
>
> Is this a problem with namedtuples, ipython or just a feature?

I think that it is a problem with the canSequence function.


Oscar



More information about the Python-list mailing list