Velocity Reviews > Tuple slices

# Tuple slices

George Sakkis
Guest
Posts: n/a

 01-24-2005
Why does slicing a tuple returns a new tuple instead of a view of the existing one, given that
tuples are immutable ? I ended up writing a custom ImmutableSequence class that does this, but I
wonder why it is not implemented for tuples.

George

Fredrik Lundh
Guest
Posts: n/a

 01-24-2005
George Sakkis wrote:

> Why does slicing a tuple returns a new tuple instead of a view of the existing one, given that
> tuples are immutable ?

really?

>>> a = 1, 2, 3
>>> b = a[:]
>>> a is b

True

</F>

Steven Bethard
Guest
Posts: n/a

 01-24-2005
Fredrik Lundh wrote:
> George Sakkis wrote:
>
>>Why does slicing a tuple returns a new tuple instead of a view of the existing one, given that
>>tuples are immutable ?

>
> really?
>
>
>>>>a = 1, 2, 3
>>>>b = a[:]
>>>>a is b

> True

My impression was that full tuple copies didn't actually copy, but that
slicing a subset of a tuple might. Not exactly sure how to test this, but:

py> a = 1, 2, 3
py> a[:2] is a[:2]
False

So _something_ at least is different between the two slices...

Steve

Pedro Werneck
Guest
Posts: n/a

 01-24-2005
On Mon, 24 Jan 2005 18:45:46 +0100
"Fredrik Lundh" <(E-Mail Removed)> wrote:

> George Sakkis wrote:
>
> > Why does slicing a tuple returns a new tuple instead of a view of
> > the existing one, given that tuples are immutable ?

>
> really?

Well... seems like this case is optimized to return the original tuple
just incrementing its reference count and returning

tupleobject.c, 330-335

if (ilow == 0 && ihigh == a->ob_size && PyTuple_CheckExact(a)) {
Py_INCREF(a);
return (PyObject *)a;
}

>
> >>> a = 1, 2, 3
> >>> b = a[:]
> >>> a is b

> True
>
> </F>
>
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list

Pedro Werneck
Guest
Posts: n/a

 01-24-2005
On Mon, 24 Jan 2005 18:45:46 +0100
"Fredrik Lundh" <(E-Mail Removed)> wrote:

> George Sakkis wrote:
>
> > Why does slicing a tuple returns a new tuple instead of a view of
> > the existing one, given that tuples are immutable ?

>
> really?

Well... seems like this case (slicing the whole tuple) is optimized to
return the original tuple just incrementing its reference count and returning

tupleobject.c, 330-335

if (ilow == 0 && ihigh == a->ob_size && PyTuple_CheckExact(a)) {
Py_INCREF(a);
return (PyObject *)a;
}

>
> >>> a = 1, 2, 3
> >>> b = a[:]
> >>> a is b

> True
>
> </F>
>
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list

Fredrik Lundh
Guest
Posts: n/a

 01-24-2005
Steven Bethard wrote:

>>>>>a = 1, 2, 3
>>>>>b = a[:]
>>>>>a is b

>> True

>
> My impression was that full tuple copies didn't actually copy, but that slicing a subset of a
> tuple might. Not exactly sure how to test this, but:
>
> py> a = 1, 2, 3
> py> a[:2] is a[:2]
> False

yup. and to figure out why things are done this way, consider this case:

>>> a = give_me_a_huge_tuple()
>>> len(a)

(a rather large number)
>>> b = a[:2]
>>> del a

(IIRC, I proposed to add "substrings" when I implemented the Unicode string
type, but that idea was rejected, for the very same "and how do you get rid of
the original object" reason)

</F>

Steven Bethard
Guest
Posts: n/a

 01-24-2005
Fredrik Lundh wrote:
> Steven Bethard wrote:
>>
>>My impression was that full tuple copies didn't actually copy, but that slicing a subset of a
>>tuple might. Not exactly sure how to test this, but:
>>
>>py> a = 1, 2, 3
>>py> a[:2] is a[:2]
>>False

>
> yup. and to figure out why things are done this way, consider this case:
>
> >>> a = give_me_a_huge_tuple()
> >>> len(a)

> (a rather large number)
> >>> b = a[:2]
> >>> del a

>
> (IIRC, I proposed to add "substrings" when I implemented the Unicode string
> type, but that idea was rejected, for the very same "and how do you get rid of
> the original object" reason)

Ahh. Yeah, that seems sensible. I don't think I've ever written code
like that, but if I did, I'd almost certainly want it to work as it does
now...

Steve

Jeff Epler
Guest
Posts: n/a

 01-24-2005
The cpython implementation stores tuples in memory like this:
[common fields for all Python objects]
[common fields for all variable-size python objects, including tuple size]
[fields specific to tuple objects, if any]
[array of PyObject*, one for each item in the tuple]
This way of storing variable-size Python objects was chosen in part
because it reuqires only one allocation for an object, not two.
However, there is no way for one tuple to point to a slice of another
tuple.

there's no reason that some other python implementation couldn't make a
different choice.

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFB9V1/Jd01MZaTXX0RAnDMAJ0f2v26tba9j46KsYV3SkylB51KlQCfeT tK
=+SO0
-----END PGP SIGNATURE-----

George Sakkis
Guest
Posts: n/a

 01-24-2005

"Fredrik Lundh" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Steven Bethard wrote:
>
> >>>>>a = 1, 2, 3
> >>>>>b = a[:]
> >>>>>a is b
> >> True

> >
> > My impression was that full tuple copies didn't actually copy, but that slicing a subset of a
> > tuple might. Not exactly sure how to test this, but:
> >
> > py> a = 1, 2, 3
> > py> a[:2] is a[:2]
> > False

>
> yup. and to figure out why things are done this way, consider this case:
>
> >>> a = give_me_a_huge_tuple()
> >>> len(a)

> (a rather large number)
> >>> b = a[:2]
> >>> del a

>
> (IIRC, I proposed to add "substrings" when I implemented the Unicode string
> type, but that idea was rejected, for the very same "and how do you get rid of
> the original object" reason)
>
> </F>

Fair enough. So perhaps the question is whether such cases are more regular than something like:
a = give_me_a_huge_tuple()
slices = [a[i:j] for i in xrange(len(a)) for j in xrange(i+1, len(a)+1)]

George

Peter Hansen
Guest
Posts: n/a

 01-24-2005
George Sakkis wrote:
> Fair enough. So perhaps the question is whether such cases are more regular than something like:
> a = give_me_a_huge_tuple()
> slices = [a[i:j] for i in xrange(len(a)) for j in xrange(i+1, len(a)+1)]

I believe the general usage of tuples tends to mean that
"give_me_a_huge_tuple()" just doesn't happen except with
those who insist on using tuples as though they were nothing

If you use a tuple the way it was apparently intended, you
are extraordinarily unlikely to find yourself with a
huge one requiring slicing in such a way that you care
whether it is a "view" or a new object.

-Peter