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


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

Re: Tuples and immutability

Started byDuncan Booth <duncan.booth@invalid.invalid>
First post2014-03-07 09:33 +0000
Last post2014-03-08 19:55 -0700
Articles 8 on this page of 108 — 24 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Tuples and immutability Duncan Booth <duncan.booth@invalid.invalid> - 2014-03-07 09:33 +0000
    Re: Tuples and immutability Ben Finney <ben+python@benfinney.id.au> - 2014-03-07 22:04 +1100
    Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-03-07 22:11 +1100
    Re: Tuples and immutability Peter Otten <__peter__@web.de> - 2014-03-07 12:38 +0100
    Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-03-07 22:45 +1100
    Re: Tuples and immutability Alister <alister.ware@ntlworld.com> - 2014-03-07 11:51 +0000
      Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-07 11:23 -0700
    Re: Tuples and immutability Roy Smith <roy@panix.com> - 2014-03-07 08:37 -0500
    Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-08 15:17 +1300
      Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-07 21:17 -0700
        Balanced trees (was: Re: Tuples and immutability) Marko Rauhamaa <marko@pacujo.net> - 2014-03-08 10:34 +0200
          Re: Balanced trees (was: Re: Tuples and immutability) Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-08 04:03 -0700
            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-08 13:26 +0200
          Re: Balanced trees (was: Re: Tuples and immutability) Dan Stromberg <drsalists@gmail.com> - 2014-03-08 11:58 -0800
          Re: Balanced trees Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-08 20:37 +0000
            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-08 23:21 +0200
              Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-08 17:22 -0500
                Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-09 11:17 +0200
              Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-08 17:31 -0800
                Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-09 11:27 +0200
                  Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-09 14:20 -0700
                    Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-09 23:32 +0200
                      Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-09 14:37 -0700
                        Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-09 23:43 +0200
                          Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-09 15:08 -0700
                            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-10 00:24 +0200
                          Re: Balanced trees Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-09 18:04 -0600
                            Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 03:24 +0000
                      Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 03:24 +0000
                        Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-10 08:16 +0200
                          Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 08:53 +0000
                            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-10 11:41 +0200
                              Re: Balanced trees Ned Batchelder <ned@nedbatchelder.com> - 2014-03-10 06:57 -0400
                                Re: Balanced trees Rustom Mody <rustompmody@gmail.com> - 2014-03-10 09:01 -0700
                                  Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-11 02:02 +0000
                                    Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-10 22:20 -0400
                                      Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 13:29 +1100
                            Re: Balanced trees Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-10 09:51 +0000
                          Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-10 09:59 -0400
                            Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 03:20 +1100
                            Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 03:24 +1100
                              Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-10 19:08 +0200
                                Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 04:17 +1100
                                  Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-10 19:34 +0200
                                    Re: Balanced trees Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-13 12:40 -0600
                                    Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-13 23:57 +0000
                                      Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-13 20:12 -0700
                                        Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-14 05:02 +0000
                                Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-10 19:24 -0400
                                  Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 10:27 +1100
                                  Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-11 01:26 +0000
                                    Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 12:45 +1100
                                    Re: Balanced trees Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-10 21:38 -0600
                                    Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 15:28 +1100
                                      Re: Balanced trees "Rhodri James" <rhodri@wildebst.org.uk> - 2014-03-12 00:57 +0000
                                    Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-11 12:12 +0200
                                      Re: Balanced trees alex23 <wuwei23@gmail.com> - 2014-03-12 10:13 +1000
                                  Re: Balanced trees Alister <alister.ware@ntlworld.com> - 2014-03-11 09:25 +0000
                                  Re: Balanced trees Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2014-03-12 10:08 +0100
                            Re: Balanced trees Tim Chase <python.list@tim.thechases.com> - 2014-03-10 11:33 -0500
                            Re: Balanced trees Chris Angelico <rosuav@gmail.com> - 2014-03-11 03:39 +1100
                            Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-10 18:05 -0700
                              Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-10 22:13 -0400
                        Re: Balanced trees Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2014-03-10 19:57 -0400
          Re: Balanced trees Joshua Landau <joshua@landau.ws> - 2014-03-15 01:13 +0000
            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-18 00:05 +0200
              Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-18 12:26 -0700
                Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-18 22:55 +0200
                  Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-18 14:45 -0700
                    Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-19 00:03 +0200
                      Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-18 15:21 -0700
                        Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-19 01:11 +0200
                          Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-19 01:15 +0000
                            Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-19 10:49 +0200
                              Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-19 13:42 +0000
                                Re: Balanced trees Marko Rauhamaa <marko@pacujo.net> - 2014-03-19 15:54 +0200
                                Re: Balanced trees Roy Smith <roy@panix.com> - 2014-03-19 10:06 -0400
                        Re: Balanced trees Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-19 01:15 +0000
                          Re: Balanced trees Ethan Furman <ethan@stoneleaf.us> - 2014-03-19 08:15 -0700
                    Re: Balanced trees "Rhodri James" <rhodri@wildebst.org.uk> - 2014-03-20 02:16 +0000
                      Re: Balanced trees Dan Stromberg <drsalists@gmail.com> - 2014-03-19 19:34 -0700
                  Re: Balanced trees Chris Kaynor <ckaynor@zindagigames.com> - 2014-03-18 18:02 -0700
              Re: Balanced trees Daniel Stutzbach <stutzbach@google.com> - 2014-03-18 13:18 -0700
          blist in standard library  (was Re: Balanced trees) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-15 12:31 +0000
          Re: Balanced trees Daniel Stutzbach <stutzbach@google.com> - 2014-03-17 14:16 -0700
          Re: Balanced trees Joshua Landau <joshua@landau.ws> - 2014-03-18 00:08 +0000
          Re: Balanced trees Daniel Stutzbach <stutzbach@google.com> - 2014-03-17 18:01 -0700
          Re: Balanced trees Joshua Landau <joshua@landau.ws> - 2014-03-18 07:46 +0000
        Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-09 13:40 +1300
          Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-08 19:39 -0700
            Re: Tuples and immutability Marko Rauhamaa <marko@pacujo.net> - 2014-03-09 11:35 +0200
            Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-10 11:03 +1300
              Re: Tuples and immutability Terry Reedy <tjreedy@udel.edu> - 2014-03-09 19:00 -0400
              Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-09 17:42 -0600
                Re: Tuples and immutability Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 02:37 +0000
                  Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-10 02:35 -0600
                    Re: Tuples and immutability Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 09:13 +0000
                    Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-11 18:15 +1300
                Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-11 18:03 +1300
                  Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-11 04:39 -0600
                    Re: Tuples and immutability Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-11 16:46 +0000
                      Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-12 10:23 +1300
                      Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-11 17:06 -0600
                        Re: Tuples and immutability Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-12 23:20 +0000
                          Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-12 19:35 -0600
                          Re: Tuples and immutability Terry Reedy <tjreedy@udel.edu> - 2014-03-12 22:09 -0400
        Re: Tuples and immutability Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-03-09 13:45 +1300
          Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-08 19:55 -0700

Page 6 of 6 — ← Prev page 1 2 3 4 5 [6]


#68226

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-03-11 16:46 +0000
Message-ID<531f3dfb$0$29994$c3e8da3$5496439d@news.astraweb.com>
In reply to#68208
On Tue, 11 Mar 2014 04:39:39 -0600, Ian Kelly wrote:

> On Mon, Mar 10, 2014 at 11:03 PM, Gregory Ewing
> <greg.ewing@canterbury.ac.nz> wrote:
>> As far as observable effects are concerned, it's quite clear: mutable
>> objects can *always* be updated in-place, and immutable objects can
>> *never* be.
> 
> Hm. Consider the circle-ellipse problem.

Oh, not that old chestnut! The circle-ellipse problem demonstrates one 
limitation of OOP (specifically "subtype polymorphism"), as well as a 
general difficulty with hierarchical taxonomies. Mammals have hair -- 
what do you make of hairless[1] dolphins? Circle/Ellipse is not a good 
place to start from in order to critic augmented assignment in Python. 
You're starting from a place where inheritance itself is problematic, so 
naturally you're going to find problems.


> Briefly, a circle is-an ellipse, so in an inheritance hierarchy it is
> natural to make Circle a subclass of Ellipse.

Natural and wrong. It's only natural if you don't think through the 
consequences. As you go on to say:

> Now suppose the Ellipse has a stretch method that
> mutates the ellipse by changing the length of one of its axes while
> preserving the other.  To avoid violating LSP, the Circle class must
> support all the methods of its ancestor.  However it cannot, because the
> stretch method would invalidate the invariant of the Circle class that
> both of its axes must always be equal.

Right. So *Circles cannot be Ellipses*, not without violating the Liskov 
Substitution Principle. If I think that they are, I haven't thought it 
through. Nor can Ellipses be Circles. That's the problem of the Circle/
Ellipse relationship.

(Aside: the LSP is not a Law Of Physics that cannot be touched. There are 
other OOP models that don't require LSP.)

Even in the case of immutable shapes, one might not wish to inherit 
Circle from Ellipsis. Ellipses have five degrees of freedom:

2 x position
size (scale)
orientation
shape

while circles only have three:

2 x position
size

Orientation and shape are meaningless for circles! So they should not 
inherit from a class where they are meaningful: given the LSP, a subclass 
cannot be more restrictive than a superclass.


> There are a number of possible solutions.  One possibility would be to
> copy the Circle as an Ellipse and return the new object instead of
> mutating it. Then you have the situation where, given a mutable object
> x that satisfies isinstance(x, Ellipse), the stretch method *may* be
> able to update the object in-place, or it *may* not.

That is a really lousy design. Of course we are free to create classes 
with ugly, inconsistent, stupid or unworkable APIs if we like. Python 
won't stop us:

class MyList(list):
    def append(self, obj):
        if len(self) % 17 == 3:
            return self + [obj]
        super(MyList, self).append(obj)



> I can't think of a reasonable example that would replace the stretch
> method here with an augmented assignment, but then it is rather late.
> 
>> It might be the obvious way for that particular operation on that
>> particular type. 

Um, yes? Nobody suggests that a method of type X has to be the most 
obvious way for *any operation* on *any type*. What's your point?


> But what about all the others? What's the obvious way
>> to spell in-place set intersection, for example? 

I would expect it to be &=, let's find out if I'm right:

py> a = set("abcde")
py> b = a  # save a reference to it
py> c = set("cdefg")
py> a &= c
py> a, b
({'c', 'd', 'e'}, {'c', 'd', 'e'})
py> a is b
True


>> (Quickly -- no peeking at the docs!)

The only reason I'd need to look at the docs is because I always forget 
whether & is intersection and | is union, or the other way around. But 
having remembered which is which, going from & to &= was easy.


> You mean set.intersection_update?  The in-place set methods are not hard
> to remember, because they all end in _update.

And hard to spell.




[1] Technically they aren't *entirely* hairless. They may have a few 
hairs around the blowhole, and baby dolphins are born with whiskers which 
they soon lose. But from a functional perspective, they are hairless.


-- 
Steven D'Aprano

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


#68239

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2014-03-12 10:23 +1300
Message-ID<bo9d69F9vf6U1@mid.individual.net>
In reply to#68226
Steven D'Aprano wrote:
> On Tue, 11 Mar 2014 04:39:39 -0600, Ian Kelly wrote:
> 
>>On Mon, Mar 10, 2014 at 11:03 PM, Gregory Ewing
 >
>>What's the obvious way
>>>to spell in-place set intersection, for example? 
> 
> I would expect it to be &=,

That's my point -- once you know the binary operator for
an operation, the corresponding in-place operator is
obvious. But there's no established standard set of
method names for in-place operations -- each type
does its own thing.

>>You mean set.intersection_update?  The in-place set methods are not hard
>>to remember, because they all end in _update.

For that particular type, maybe, but I wouldn't trust
that rule to extend to other types.

-- 
Greg

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


#68248

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-03-11 17:06 -0600
Message-ID<mailman.8066.1394579251.18130.python-list@python.org>
In reply to#68226
On Tue, Mar 11, 2014 at 10:46 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>> There are a number of possible solutions.  One possibility would be to
>> copy the Circle as an Ellipse and return the new object instead of
>> mutating it. Then you have the situation where, given a mutable object
>> x that satisfies isinstance(x, Ellipse), the stretch method *may* be
>> able to update the object in-place, or it *may* not.
>
> That is a really lousy design. Of course we are free to create classes
> with ugly, inconsistent, stupid or unworkable APIs if we like. Python
> won't stop us:

That's true but irrelevant to my point, which was to counter the
assertion that mutable types can always be assumed to be able to
perform operations in-place.

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


#68312

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-03-12 23:20 +0000
Message-ID<5320ebce$0$29994$c3e8da3$5496439d@news.astraweb.com>
In reply to#68248
On Tue, 11 Mar 2014 17:06:43 -0600, Ian Kelly wrote:

> On Tue, Mar 11, 2014 at 10:46 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>>> There are a number of possible solutions.  One possibility would be to
>>> copy the Circle as an Ellipse and return the new object instead of
>>> mutating it. Then you have the situation where, given a mutable object
>>> x that satisfies isinstance(x, Ellipse), the stretch method *may* be
>>> able to update the object in-place, or it *may* not.
>>
>> That is a really lousy design. Of course we are free to create classes
>> with ugly, inconsistent, stupid or unworkable APIs if we like. Python
>> won't stop us:
> 
> That's true but irrelevant to my point, which was to counter the
> assertion that mutable types can always be assumed to be able to perform
> operations in-place.

"Always"? Not so fast.

This is Python. We have freedom to abuse nearly everything, and if you 
want to shoot yourself in the foot, you can. With the exception of a 
handful of things which cannot be overridden (e.g. None, numeric 
literals, syntax) you cannot strictly assume anything about anything. 
Python does not enforce that iterators raise StopIteration when empty, or 
that indexing beyond the boundaries of a sequence raises IndexError, or 
that __setitem__ of a mapping sets the key and value, or that __len__ 
returns a length.

Augmented assignment is no different. The docs describe the intention of 
the designers and the behaviour of the classes that they control, so with 
standard built-in classes like int, str, list, tuple etc. you can safely 
assume that mutable types will perform the operation in place and 
immutable types won't, but with arbitrary types from some arbitrarily 
eccentric or twisted programmer, who knows what it will do?


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

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


#68318

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-03-12 19:35 -0600
Message-ID<mailman.8118.1394674579.18130.python-list@python.org>
In reply to#68312
On Wed, Mar 12, 2014 at 5:20 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Tue, 11 Mar 2014 17:06:43 -0600, Ian Kelly wrote:
>
>> That's true but irrelevant to my point, which was to counter the
>> assertion that mutable types can always be assumed to be able to perform
>> operations in-place.
>
> "Always"? Not so fast.
>
> This is Python. We have freedom to abuse nearly everything, and if you
> want to shoot yourself in the foot, you can. With the exception of a
> handful of things which cannot be overridden (e.g. None, numeric
> literals, syntax) you cannot strictly assume anything about anything.
> Python does not enforce that iterators raise StopIteration when empty, or
> that indexing beyond the boundaries of a sequence raises IndexError, or
> that __setitem__ of a mapping sets the key and value, or that __len__
> returns a length.

Thank you; you've stated my point more succinctly than I did.

> Augmented assignment is no different. The docs describe the intention of
> the designers and the behaviour of the classes that they control, so with
> standard built-in classes like int, str, list, tuple etc. you can safely
> assume that mutable types will perform the operation in place and
> immutable types won't, but with arbitrary types from some arbitrarily
> eccentric or twisted programmer, who knows what it will do?

This got me curious about how consistent the standard library is about
this exactly, so I did some grepping.  In the standard library there
are 5 mutable types that support concatenation that I was able to
find: list, deque, array, bytearray, and Counter.  There are none that
support addition, which I find interesting in that the language
provides hooks for in-place addition but never uses them itself.

All of the classes above appear to follow the rule that if you can
concatenate an operand, you can in-place concatenate the same operand.
 The converse however does not hold:  list.__iadd__ and
Counter.__iadd__ are both more permissive in what types they will
accept than their __add__ counterparts, and especially interesting to
me is that deque implements __iadd__ but does not implement __add__ at
all.  This last in particular seems to support the assertion that +=
should be viewed more as a shorthand for an in-place operation, less
as an equivalent for x = x + y.

>>> l = [1,2,3]
>>> l + (4,5,6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>> l += (4,5,6)
>>> l
[1, 2, 3, 4, 5, 6]

>>> c = collections.Counter('mississippi')
>>> c + collections.Counter('alabama')
Counter({'s': 4, 'a': 4, 'i': 4, 'p': 2, 'm': 2, 'b': 1, 'l': 1})
>>> c + dict({'a': 4, 'l': 1, 'b': 1, 'm': 1})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Counter' and 'dict'
>>> c += dict({'a': 4, 'l': 1, 'b': 1, 'm': 1})
>>> c
Counter({'s': 4, 'a': 4, 'i': 4, 'p': 2, 'm': 2, 'b': 1, 'l': 1})

>>> d = collections.deque([1,2,3])
>>> d += [4,5,6]
>>> d
deque([1, 2, 3, 4, 5, 6])
>>> d + [7,8,9]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'collections.deque' and 'list'
>>> d.__add__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'collections.deque' object has no attribute '__add__'

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


#68319

FromTerry Reedy <tjreedy@udel.edu>
Date2014-03-12 22:09 -0400
Message-ID<mailman.8119.1394676599.18130.python-list@python.org>
In reply to#68312
On 3/12/2014 9:35 PM, Ian Kelly wrote:
> On Wed, Mar 12, 2014 at 5:20 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Tue, 11 Mar 2014 17:06:43 -0600, Ian Kelly wrote:
>>
>>> That's true but irrelevant to my point, which was to counter the
>>> assertion that mutable types can always be assumed to be able to perform
>>> operations in-place.
>>
>> "Always"? Not so fast.
>>
>> This is Python. We have freedom to abuse nearly everything, and if you
>> want to shoot yourself in the foot, you can. With the exception of a
>> handful of things which cannot be overridden (e.g. None, numeric
>> literals, syntax) you cannot strictly assume anything about anything.
>> Python does not enforce that iterators raise StopIteration when empty, or
>> that indexing beyond the boundaries of a sequence raises IndexError, or
>> that __setitem__ of a mapping sets the key and value, or that __len__
>> returns a length.
>
> Thank you; you've stated my point more succinctly than I did.
>
>> Augmented assignment is no different. The docs describe the intention of
>> the designers and the behaviour of the classes that they control, so with
>> standard built-in classes like int, str, list, tuple etc. you can safely
>> assume that mutable types will perform the operation in place and
>> immutable types won't, but with arbitrary types from some arbitrarily
>> eccentric or twisted programmer, who knows what it will do?
>
> This got me curious about how consistent the standard library is about
> this exactly, so I did some grepping.  In the standard library there
> are 5 mutable types that support concatenation that I was able to
> find: list, deque, array, bytearray, and Counter.  There are none that
> support addition, which I find interesting in that the language
> provides hooks for in-place addition but never uses them itself.
>
> All of the classes above appear to follow the rule that if you can
> concatenate an operand, you can in-place concatenate the same operand.
>   The converse however does not hold:  list.__iadd__ and
> Counter.__iadd__ are both more permissive in what types they will
> accept than their __add__ counterparts, and especially interesting to
> me is that deque implements __iadd__ but does not implement __add__ at
> all.  This last in particular seems to support the assertion that +=
> should be viewed more as a shorthand for an in-place operation, less
> as an equivalent for x = x + y.
>
>>>> l = [1,2,3]
>>>> l + (4,5,6)
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: can only concatenate list (not "tuple") to list
>>>> l += (4,5,6)
>>>> l
> [1, 2, 3, 4, 5, 6]

Like it or not, one should actually think of 'somelist += iterable' as 
equivalent to 'somelist.extend(iterable)'.  Without looking at the C 
code, I  suspect that the latter is the internal implementation. 
Collections.deque also has .extend. Collections.Counter has .update and 
that is += seems to be doing.


>>>> c = collections.Counter('mississippi')
>>>> c + collections.Counter('alabama')
> Counter({'s': 4, 'a': 4, 'i': 4, 'p': 2, 'm': 2, 'b': 1, 'l': 1})
>>>> c + dict({'a': 4, 'l': 1, 'b': 1, 'm': 1})
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for +: 'Counter' and 'dict'
>>>> c += dict({'a': 4, 'l': 1, 'b': 1, 'm': 1})
>>>> c
> Counter({'s': 4, 'a': 4, 'i': 4, 'p': 2, 'm': 2, 'b': 1, 'l': 1})
>
>>>> d = collections.deque([1,2,3])
>>>> d += [4,5,6]
>>>> d
> deque([1, 2, 3, 4, 5, 6])
>>>> d + [7,8,9]
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for +: 'collections.deque' and 'list'
>>>> d.__add__
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> AttributeError: 'collections.deque' object has no attribute '__add__'
>


-- 
Terry Jan Reedy

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


#68056

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2014-03-09 13:45 +1300
Message-ID<bo1rseFlmgoU1@mid.individual.net>
In reply to#68023
Ian Kelly wrote:

> I already mentioned this earlier in the thread, but a balanced binary
> tree might implement += as node insertion and then return a different
> object if the balancing causes the root node to change.

That would be a really bad way to design a binary tree
implementation. What if there is another reference to
the tree somewhere? It's still going to be referring to
the old root object, and will have an incoherent view
of the data -- partly old and partly new.

If you're going to have a mutable tree, it needs to be
encapsulated in a stable top-level object.

-- 
Greg

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


#68063

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-03-08 19:55 -0700
Message-ID<mailman.7946.1394333769.18130.python-list@python.org>
In reply to#68056
On Sat, Mar 8, 2014 at 5:45 PM, Gregory Ewing
<greg.ewing@canterbury.ac.nz> wrote:
> Ian Kelly wrote:
>
>> I already mentioned this earlier in the thread, but a balanced binary
>> tree might implement += as node insertion and then return a different
>> object if the balancing causes the root node to change.
>
>
> That would be a really bad way to design a binary tree
> implementation. What if there is another reference to
> the tree somewhere? It's still going to be referring to
> the old root object, and will have an incoherent view
> of the data -- partly old and partly new.
>
> If you're going to have a mutable tree, it needs to be
> encapsulated in a stable top-level object.

Well, as I parenthetically noted the first time I brought it up,
"whether this is good design is tangential; it's a possible design".
The language shouldn't be written such that only those designs deemed
"good" by some external committee can be implemented.  What you
dismiss as "really bad" may be exactly what somebody else needs, and
maybe they intend that there won't be other references.

[toc] | [prev] | [standalone]


Page 6 of 6 — ← Prev page 1 2 3 4 5 [6]

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


csiph-web