Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #69746 > unrolled thread

Mutable objects inside tuples - good or bad?

Started byJohn Ladasky <john_ladasky@sbcglobal.net>
First post2014-04-05 23:53 -0700
Last post2014-04-08 02:53 +0000
Articles 12 — 8 participants

Back to article view | Back to comp.lang.python


Contents

  Mutable objects inside tuples - good or bad? John Ladasky <john_ladasky@sbcglobal.net> - 2014-04-05 23:53 -0700
    Re: Mutable objects inside tuples - good or bad? Gary Herron <gary.herron@islandtraining.com> - 2014-04-06 00:25 -0700
    Re: Mutable objects inside tuples - good or bad? Devin Jeanpierre <jeanpierreda@gmail.com> - 2014-04-06 00:55 -0700
      Re: Mutable objects inside tuples - good or bad? Rustom Mody <rustompmody@gmail.com> - 2014-04-06 08:07 -0700
    Re: Mutable objects inside tuples - good or bad? Chris Angelico <rosuav@gmail.com> - 2014-04-06 18:25 +1000
    Re: Mutable objects inside tuples - good or bad? Devin Jeanpierre <jeanpierreda@gmail.com> - 2014-04-06 04:01 -0700
    Re: Mutable objects inside tuples - good or bad? Paul Kölle <paul@subsignal.org> - 2014-04-07 17:26 +0200
    Re: Mutable objects inside tuples - good or bad? Chris Angelico <rosuav@gmail.com> - 2014-04-08 01:44 +1000
    Re: Mutable objects inside tuples - good or bad? Paul Kölle <paul@subsignal.org> - 2014-04-07 21:46 +0200
    Re: Mutable objects inside tuples - good or bad? Chris Angelico <rosuav@gmail.com> - 2014-04-08 08:47 +1000
    Re: Mutable objects inside tuples - good or bad? Terry Reedy <tjreedy@udel.edu> - 2014-04-07 20:16 -0400
      Re: Mutable objects inside tuples - good or bad? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-08 02:53 +0000

#69746 — Mutable objects inside tuples - good or bad?

FromJohn Ladasky <john_ladasky@sbcglobal.net>
Date2014-04-05 23:53 -0700
SubjectMutable objects inside tuples - good or bad?
Message-ID<89df32f9-c8ae-4b7b-bfc4-01c574aabcae@googlegroups.com>
I find this programming pattern to be useful... but can it cause problems?

Python 3.3.2+ (default, Feb 28 2014, 00:52:16) 
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = (a,b)
>>> c
([1, 2, 3], [4, 5, 6])
>>> c[0][0] = 0
>>> c
([0, 2, 3], [4, 5, 6])

Comments appreciated.

[toc] | [next] | [standalone]


#69747

FromGary Herron <gary.herron@islandtraining.com>
Date2014-04-06 00:25 -0700
Message-ID<mailman.8939.1396769507.18130.python-list@python.org>
In reply to#69746
On 04/05/2014 11:53 PM, John Ladasky wrote:
> I find this programming pattern to be useful... but can it cause problems?
No.

What kind of problems are you considering?  It won't break Python. It's 
perfectly legal code.

The tuple c is still immutable, consisting of two specific objects, and 
(as always) without regard to the specifics or contents of those two 
objects.

Gary Herron


>
> Python 3.3.2+ (default, Feb 28 2014, 00:52:16)
> [GCC 4.8.1] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> a = [1,2,3]
>>>> b = [4,5,6]
>>>> c = (a,b)
>>>> c
> ([1, 2, 3], [4, 5, 6])
>>>> c[0][0] = 0
>>>> c
> ([0, 2, 3], [4, 5, 6])
>
> Comments appreciated.

[toc] | [prev] | [next] | [standalone]


#69749

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2014-04-06 00:55 -0700
Message-ID<mailman.8940.1396771007.18130.python-list@python.org>
In reply to#69746
On Sun, Apr 6, 2014 at 12:25 AM, Gary Herron
<gary.herron@islandtraining.com> wrote:
> On 04/05/2014 11:53 PM, John Ladasky wrote:
>>
>> I find this programming pattern to be useful... but can it cause problems?
>
> No.
>
> What kind of problems are you considering?  It won't break Python. It's
> perfectly legal code.

Agreed. Putting mutable objects inside tuples is common and totally OK.

> The tuple c is still immutable, consisting of two specific objects, and (as
> always) without regard to the specifics or contents of those two objects.

You can choose to define mutability that way, but in many contexts
you'll find that definition not very useful.

c is such that you could have another variable d, where the following
interpreter session fragment is easily possible:

>>> c == d
True
>>> foo(c)
>>> c == d
False

-- Devin

>> Python 3.3.2+ (default, Feb 28 2014, 00:52:16)
>> [GCC 4.8.1] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>>
>>>>> a = [1,2,3]
>>>>> b = [4,5,6]
>>>>> c = (a,b)
>>>>> c
>>
>> ([1, 2, 3], [4, 5, 6])
>>>>>
>>>>> c[0][0] = 0
>>>>> c
>>
>> ([0, 2, 3], [4, 5, 6])
>>
>> Comments appreciated.
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list

[toc] | [prev] | [next] | [standalone]


#69768

FromRustom Mody <rustompmody@gmail.com>
Date2014-04-06 08:07 -0700
Message-ID<873b7df7-f213-4d84-a300-ef34ea1dd0a2@googlegroups.com>
In reply to#69749
On Sunday, April 6, 2014 1:40:58 PM UTC+5:45, Devin Jeanpierre wrote:
> 
> You can choose to define mutability that way, but in many contexts
> you'll find that definition not very useful.
> 
> c is such that you could have another variable d, where the following
> interpreter session fragment is easily possible:
> 
> 
> >>> c == d
> True
> >>> foo(c)
> >>> c == d
> False

Its called referential transparency (or rather the lack of it)
And that is why it (Johns question) is not a good idea.

In general worshipping overzealously at the altar of RT produces functional
programming. To the non-zealots this has the characteristic of 
"Throw out baby with bathwater"

On the other hand imperative programming is a source of more problems than
people realize:
http://blog.languager.org/2012/11/imperative-programming-lessons-not.html

[toc] | [prev] | [next] | [standalone]


#69757

FromChris Angelico <rosuav@gmail.com>
Date2014-04-06 18:25 +1000
Message-ID<mailman.8944.1396772745.18130.python-list@python.org>
In reply to#69746
On Sun, Apr 6, 2014 at 5:55 PM, Devin Jeanpierre <jeanpierreda@gmail.com> wrote:
> On Sun, Apr 6, 2014 at 12:25 AM, Gary Herron
> <gary.herron@islandtraining.com> wrote:
>> On 04/05/2014 11:53 PM, John Ladasky wrote:
>>>
>>> I find this programming pattern to be useful... but can it cause problems?
>>
>> No.
>>
>> What kind of problems are you considering?  It won't break Python. It's
>> perfectly legal code.
>
> Agreed. Putting mutable objects inside tuples is common and totally OK.

There are many programming habits that can cause problems, even though
they won't break Python and are legal code. :)

>> The tuple c is still immutable, consisting of two specific objects, and (as
>> always) without regard to the specifics or contents of those two objects.
>
> You can choose to define mutability that way, but in many contexts
> you'll find that definition not very useful.
>
> c is such that you could have another variable d, where the following
> interpreter session fragment is easily possible:
>
>>>> c == d
> True
>>>> foo(c)
>>>> c == d
> False

What you're looking at here is hashability, not mutability. Compare:

>>> a = (1,2,3)
>>> hash(a)
2528502973977326415
>>> b = ([1],[2],[3])
>>> hash(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Both tuples are immutable, but the former is hashable because all its
members are hashable, while the latter is not. You can't trust that
equality with b is constant:

>>> c = ([1],[2],[3])
>>> b == c
True
>>> b[2][0]=4
>>> b == c
False

Going back to the original question, though: I do not believe that
putting mutable objects inside tuples is a problem. I've done it
frequently myself, and it's never caused confusion. So go right ahead,
do it if it makes sense!

ChrisA

[toc] | [prev] | [next] | [standalone]


#69761

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2014-04-06 04:01 -0700
Message-ID<mailman.8947.1396782118.18130.python-list@python.org>
In reply to#69746
On Sun, Apr 6, 2014 at 1:25 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Sun, Apr 6, 2014 at 5:55 PM, Devin Jeanpierre <jeanpierreda@gmail.com> wrote:
>> Agreed. Putting mutable objects inside tuples is common and totally OK.
>
> There are many programming habits that can cause problems, even though
> they won't break Python and are legal code. :)

Yes, but this isn't one of them.

>> c is such that you could have another variable d, where the following
>> interpreter session fragment is easily possible:
>>
>>>>> c == d
>> True
>>>>> foo(c)
>>>>> c == d
>> False
>
> What you're looking at here is hashability, not mutability. Compare:

No, that is not what I am looking at. There are hashable objects with
the property I described, and unhashable objects without it.

My point in that example was that sometimes it is more useful to talk
about entire objects and their behavior as a whole. Calling the object
"immutable" when it has mutable state is misleading in this context.

-- Devin

[toc] | [prev] | [next] | [standalone]


#69817

FromPaul Kölle <paul@subsignal.org>
Date2014-04-07 17:26 +0200
Message-ID<mailman.8982.1396884419.18130.python-list@python.org>
In reply to#69746
Am 06.04.2014 09:25, schrieb Gary Herron:
> On 04/05/2014 11:53 PM, John Ladasky wrote:
>> I find this programming pattern to be useful... but can it cause
>> problems?
> No.
>
> What kind of problems are you considering?  It won't break Python. It's
> perfectly legal code.
>
> The tuple c is still immutable, consisting of two specific objects, and
> (as always) without regard to the specifics or contents of those two
> objects.
It seems a tuple's immutability is debatable, or is this another 
instance of the small-integer-reuse-implementation-detail-artifact?

Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> a = ([1,2],[3,4])
 >>> b = a
 >>> a is b
True
 >>> a == b
True
 >>> c = (1,2,3)
 >>> d = (1,2,3)
 >>> c is d
False
 >>> c == d
True

cheers
  Paul

[toc] | [prev] | [next] | [standalone]


#69818

FromChris Angelico <rosuav@gmail.com>
Date2014-04-08 01:44 +1000
Message-ID<mailman.8983.1396885455.18130.python-list@python.org>
In reply to#69746
On Tue, Apr 8, 2014 at 1:26 AM, Paul Kölle <pkoelle@gmail.com> wrote:
> It seems a tuple's immutability is debatable, or is this another instance of
> the small-integer-reuse-implementation-detail-artifact?
>
> Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
> [GCC 4.4.5] on linux2
>
> Type "help", "copyright", "credits" or "license" for more information.
>>>> a = ([1,2],[3,4])
>>>> b = a
>>>> a is b
> True
>>>> a == b
> True
>>>> c = (1,2,3)
>>>> d = (1,2,3)
>>>> c is d
> False
>>>> c == d
> True

That's nothing to do with mutability or reuse. With a and b, you
assigned one to be the same as the other, so they are by definition
identical (and equal; tuples assume that identity implies equality,
even though that may not be true of their elements). With c and d, you
assigned separate tuples, so they're allowed to be separate objects.
I'm not sure if they're allowed to be constant-folded, but CPython
apparently isn't doing so. They are still equal, though; they contain
equal elements, ergo they are equal. (Note that (1, 2, 3) and (1.0,
2.0, 3.0) are equal, but they obviously can't be identical any more
than "1 is 1.0" can ever be True.)

ChrisA

[toc] | [prev] | [next] | [standalone]


#69819

FromPaul Kölle <paul@subsignal.org>
Date2014-04-07 21:46 +0200
Message-ID<mailman.8984.1396900024.18130.python-list@python.org>
In reply to#69746
Am 07.04.2014 17:44, schrieb Chris Angelico:
> On Tue, Apr 8, 2014 at 1:26 AM, Paul Kölle <pkoelle@gmail.com> wrote:
>> It seems a tuple's immutability is debatable, or is this another instance of
>> the small-integer-reuse-implementation-detail-artifact?
>>
>> Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
>> [GCC 4.4.5] on linux2
>>
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> a = ([1,2],[3,4])
>>>>> b = a
>>>>> a is b
>> True
>>>>> a == b
>> True
>>>>> c = (1,2,3)
>>>>> d = (1,2,3)
>>>>> c is d
>> False
>>>>> c == d
>> True
>
> That's nothing to do with mutability or reuse. With a and b, you
> assigned one to be the same as the other, so they are by definition
> identical (and equal; tuples assume that identity implies equality,
> even though that may not be true of their elements). With c and d, you
> assigned separate tuples, so they're allowed to be separate objects.
> I'm not sure if they're allowed to be constant-folded, but CPython
> apparently isn't doing so. They are still equal, though; they contain
> equal elements, ergo they are equal. (Note that (1, 2, 3) and (1.0,
> 2.0, 3.0) are equal, but they obviously can't be identical any more
> than "1 is 1.0" can ever be True.)
>
> ChrisA
>
Thanks Chris, stupid error indeed ;)

cheers
  Paul

[toc] | [prev] | [next] | [standalone]


#69820

FromChris Angelico <rosuav@gmail.com>
Date2014-04-08 08:47 +1000
Message-ID<mailman.8985.1396910826.18130.python-list@python.org>
In reply to#69746
On Tue, Apr 8, 2014 at 5:46 AM, Paul Kölle <paul@subsignal.org> wrote:
> Thanks Chris, stupid error indeed ;)

Error, at least :) This is why we have a mailing list: errors,
inaccuracies, and typos, regardless of who makes them or when, are
pretty much guaranteed to be caught.

ChrisA

[toc] | [prev] | [next] | [standalone]


#69822

FromTerry Reedy <tjreedy@udel.edu>
Date2014-04-07 20:16 -0400
Message-ID<mailman.8987.1396916189.18130.python-list@python.org>
In reply to#69746
On 4/7/2014 11:26 AM, Paul Kölle wrote:

>  >>> c = (1,2,3)
>  >>> d = (1,2,3)
>  >>> c is d
> False

An implementation would be allowed to make that True, as it does for 
small ints and short strings that could be identifiers.

 >>> a = 'one'
 >>> b = 'one'
 >>> a == b; a is b
True
True

However, duplicate tuples are much rarer than duplicate identifier strings.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#69827

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-04-08 02:53 +0000
Message-ID<534364af$0$29993$c3e8da3$5496439d@news.astraweb.com>
In reply to#69822
On Mon, 07 Apr 2014 20:16:05 -0400, Terry Reedy wrote:

> On 4/7/2014 11:26 AM, Paul Kölle wrote:
> 
>>  >>> c = (1,2,3)
>>  >>> d = (1,2,3)
>>  >>> c is d
>> False
> 
> An implementation would be allowed to make that True, as it does for
> small ints and short strings that could be identifiers.

And indeed, that happens in at least one circumstance in Python 3.3:

py> a, b = [(1, 2, 3) for _ in range(2)]
py> a is b
True

But:

py> x = 3
py> a, b = [(1, 2, x) for _ in range(2)]
py> a is b
False


As Terry knows, but for the benefit of others who may not, the re-use of 
objects leading to object identity ("a is b") is an implementation detail 
which *cannot be relied on*. It can change without notice, and is not a 
promise of the language.


>  >>> a = 'one'
>  >>> b = 'one'
>  >>> a == b; a is b
> True
> True

In this case, it is a promise of the language that a will equal b: a and 
b must be bound to strings with the same value. But an implementation 
detail whether Python creates two strings, both with value "one", or just 
a single string, and uses it for both a and b.



-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web