Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #67151 > unrolled thread
| Started by | Eric Jacoboni <eric.jacoboni@gmail.com> |
|---|---|
| First post | 2014-02-27 17:01 +0100 |
| Last post | 2014-03-01 18:15 -0800 |
| Articles | 19 on this page of 39 — 13 participants |
Back to article view | Back to comp.lang.python
Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-02-27 17:01 +0100
Re: Tuples and immutability Zachary Ware <zachary.ware+pylist@gmail.com> - 2014-02-27 10:13 -0600
Re: Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-02-27 17:27 +0100
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-02-28 03:33 +1100
Re: Tuples and immutability Zachary Ware <zachary.ware+pylist@gmail.com> - 2014-02-27 10:47 -0600
Re: Tuples and immutability Nick Timkovich <prometheus235@gmail.com> - 2014-02-27 15:47 -0600
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-02-28 08:52 +1100
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-02-27 15:18 -0700
Re: Tuples and immutability Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2014-03-01 18:55 +0000
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-02-28 03:14 +1100
Re: Tuples and immutability Marko Rauhamaa <marko@pacujo.net> - 2014-02-27 18:19 +0200
Re: Tuples and immutability John O'Hagan <research@johnohagan.com> - 2014-02-28 16:17 +1100
Re: Tuples and immutability Marko Rauhamaa <marko@pacujo.net> - 2014-02-28 09:54 +0200
Re: Tuples and immutability Joshua Landau <joshua@landau.ws> - 2014-02-28 14:41 +0000
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-03-01 01:43 +1100
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-02-28 16:22 -0800
Re: Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-03-01 02:27 +0100
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-02-28 20:45 -0800
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-02-28 22:34 -0700
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-02-28 21:50 -0800
Re: Tuples and immutability Ned Batchelder <ned@nedbatchelder.com> - 2014-03-01 12:56 -0500
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-02-28 22:26 -0700
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-03-01 12:39 +1100
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-02-28 22:16 -0700
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-02-28 22:16 -0800
Re: Tuples and immutability Chris Angelico <rosuav@gmail.com> - 2014-03-01 17:29 +1100
Re: Tuples and immutability Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-01 14:54 +0000
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-03-01 13:01 -0800
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-02-28 22:25 -0800
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-01 12:45 -0700
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-03-01 13:21 -0800
Re: Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-03-02 03:04 +0100
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-03-01 18:28 -0800
Re: Tuples and immutability Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-02 05:32 -0700
Re: Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-03-02 14:38 +0100
Re: Tuples and immutability Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-02 14:05 +0000
Re: Tuples and immutability Eric Jacoboni <eric.jacoboni@gmail.com> - 2014-03-02 15:17 +0100
Re: Tuples and immutability "albert visser" <albert.visser@gmail.com> - 2014-03-02 15:37 +0100
Re: Tuples and immutability "Mark H. Harris" <harrismh777@gmail.com> - 2014-03-01 18:15 -0800
Page 2 of 2 — ← Prev page 1 [2]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2014-03-01 12:56 -0500 |
| Message-ID | <mailman.7521.1393696597.18130.python-list@python.org> |
| In reply to | #67295 |
On 3/1/14 12:50 AM, Mark H. Harris wrote: > On Friday, February 28, 2014 11:34:56 PM UTC-6, Ian wrote: > >> One very common example of tuples containing lists is when lists are >> passed to any function that accepts *args, because the extra arguments >> are passed in a tuple. A similarly common example is when returning >> multiple objects from a function, and one of them happens to be a >> list, because again they are returned in a tuple. > >> def f(*args): >> print(args) >> return (args[1:] >> >> >>> result = f(1, 2, 3, [4, 5]) >> (1, 2, 3, [4, 5]) >> >>> print(result) >> (2, 3, [4, 5]) > > I agree Ian... good points all. ... again, I'm not arguing with anyone... just saying that an error (whatever we mean by that) should not half-way-fail.... we are only pointing out the problem... we have not idea what the solution is yet. > > Intuitively everyone can see that there is a problem here... the debate cannot be answered either because of the inherent design of python (almost all of which we love). So, as they say, what is a mother to do? ... I mean, some people's kids... > > I don't know how I propose to handle the problem... I think the first step is getting everyone to agree that there IS a problem... then debate how to tackle the solution proposals. > > marcus > Everyone can agree that it is not great to raise an exception and also leave the list modified. But I very much doubt that anything will be done to change the situation. All of the solutions are too extreme, and bring their own infelicities, and the actual problems caused by this scenario are vanishingly small. BTW: I also am mystified why you uses ellipses to end your sentences, surely one period would be enough? :) -- Ned Batchelder, http://nedbatchelder.com
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-02-28 22:26 -0700 |
| Message-ID | <mailman.7500.1393651610.18130.python-list@python.org> |
| In reply to | #67275 |
On Fri, Feb 28, 2014 at 6:27 PM, Eric Jacoboni <eric.jacoboni@gmail.com> wrote: > Anyway, the TypeError should rollback, not commit the mistake. The Python interpreter isn't a database. It can't rollback the object because the operation that was performed may not be reversible. Consider for example a socket class where the += operator is overloaded to send a message on the socket. The message can't be unsent.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-01 12:39 +1100 |
| Message-ID | <mailman.7491.1393637948.18130.python-list@python.org> |
| In reply to | #67260 |
On Sat, Mar 1, 2014 at 11:22 AM, Mark H. Harris <harrismh777@gmail.com> wrote: > lists within a tuple should be converted to tuples. If you want a tuple to hold a list, make it a list in the first place. Tuples should not be changed... and as you point out... half changing a tuple is not a good condition if there is an exception... > A tuple is perfectly fine containing a list. If you want a tuple to be "recursively immutable", then you're talking about hashability, and *then* yes, you need to convert everything into tuples - but a tuple is not just an immutable list. The two are quite different in pupose. > I really think this is a bug; honestly. IMHO it should be an error to use += with an immutable type and that means not at all. In other words, the list should not even be considered, because we're talking about changing a tuple... which should not be changed (nor should its members be changed). > Definitely not! Incrementing an integer with += is a perfectly normal thing to do: x = 5 x += 1 It's just a matter of knowing the language and understanding what's going on. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-02-28 22:16 -0700 |
| Message-ID | <mailman.7499.1393651028.18130.python-list@python.org> |
| In reply to | #67260 |
On Fri, Feb 28, 2014 at 5:22 PM, Mark H. Harris <harrismh777@gmail.com> wrote:
> I really think this is a bug; honestly. IMHO it should be an error to use += with an immutable type and that means not at all. In other words, the list should not even be considered, because we're talking about changing a tuple... which should not be changed (nor should its members be changed).
How would you propose doing that? Bear in mind that while Python
knows that tuples specifically are immutable, it doesn't generally
know whether a type is immutable. The best it can do is try the
operation and raise a TypeError if it fails. So you can special-case
the code for += to fail earlier if the left side of the assignment is
an tuple index, but it's not currently possible to do the same for
arbitrary immutable user types.
Even if that is solved, how you do propose preventing the simple workaround:
tup = (0, [1, 2, 3], 4)
thelist = tup[1]
thelist += [5, 6]
which currently works just fine.
I don't think that entirely disallowing mutable objects inside tuples
is an acceptable solution. For one, it would mean never allowing
instances of custom classes. They could then basically only contain
strings, numbers, frozensets, and other tuples. For another, my
experience suggests that if I'm putting a list inside a tuple in the
first place, I am generally not relying on the immutability of that
tuple anyway, so I don't really see this as fixing an actual problem.
The usual reason for wanting an immutable object is to hash it, and a
tuple containing a list already can't be hashed.
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-02-28 22:16 -0800 |
| Message-ID | <dc08f190-e4d3-40bc-9fd3-9fa24f757816@googlegroups.com> |
| In reply to | #67291 |
On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote: > How would you propose doing that? Bear in mind that while Python > knows that tuples specifically are immutable, it doesn't generally > know whether a type is immutable. hi Ian, consider the problem... its a "cake" and "eat it too" scenario... you can't have your cake and eat it too.... This is what I mean... the error message is telling the user that it cannot do what he has requested, and yet IT DID. You have one of two scenarios: 1) the message is arbitrarily lying and it really can assign an immutable's item... (and it did!) or 2) It really should NOT assign an immutables item (the message is truth) but the action was "allowed" anyway despite the protocol and accepted policy... in which case the two scenarios add up to a giant logical inconsistency... QED a bug. There really is no way to get around this from the average user's perspective. And therefore, this is going to come up again and again and again... because coders don't like unexpected logical inconsistencies. It is not helpful either to explain it away by knowing how the policy works under the covers... the average user of the python language should not have to understand the policy of the underlying substructure... 1) either they can't assign the list item of an immutable tuple type (and the action is a flaw, say bug of 2) they really CAN set the immutable's list item type (which it did!) and the message is bogus. Its one way or the other.... we can't have our cake and eat it too... this is (one way or the other) a bug. IMHO
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-01 17:29 +1100 |
| Message-ID | <mailman.7503.1393655392.18130.python-list@python.org> |
| In reply to | #67296 |
On Sat, Mar 1, 2014 at 5:16 PM, Mark H. Harris <harrismh777@gmail.com> wrote: > This is what I mean... the error message is telling the user that it cannot do what he has requested, and yet IT DID. You have one of two scenarios: 1) the message is arbitrarily lying and it really can assign an immutable's item... (and it did!) or 2) It really should NOT assign an immutables item (the message is truth) but the action was "allowed" anyway despite the protocol and accepted policy... in which case the two scenarios add up to a giant logical inconsistency... QED a bug. > It did not assign anything. The error was raised because the tuple rejects item assignment. It's that simple. The object was mutated before the assignment was attempted. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2014-03-01 14:54 +0000 |
| Message-ID | <mailman.7514.1393685683.18130.python-list@python.org> |
| In reply to | #67296 |
On 01/03/2014 06:16, Mark H. Harris wrote: > On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote: > >> How would you propose doing that? Bear in mind that while Python >> knows that tuples specifically are immutable, it doesn't generally >> know whether a type is immutable. > > > hi Ian, consider the problem... its a "cake" and "eat it too" scenario... you can't have your cake and eat it too.... > > This is what I mean... the error message is telling the user that it cannot do what he has requested, and yet IT DID. You have one of two scenarios: 1) the message is arbitrarily lying and it really can assign an immutable's item... (and it did!) or 2) It really should NOT assign an immutables item (the message is truth) but the action was "allowed" anyway despite the protocol and accepted policy... in which case the two scenarios add up to a giant logical inconsistency... QED a bug. > > There really is no way to get around this from the average user's perspective. And therefore, this is going to come up again and again and again... because coders don't like unexpected logical inconsistencies. > > It is not helpful either to explain it away by knowing how the policy works under the covers... the average user of the python language should not have to understand the policy of the underlying substructure... > > 1) either they can't assign the list item of an immutable tuple type (and the action is a flaw, say bug > > of > > 2) they really CAN set the immutable's list item type (which it did!) and the message is bogus. > > > Its one way or the other.... we can't have our cake and eat it too... this is (one way or the other) a bug. > > IMHO > would you please be kind enough to use plain English... your use of sentences like this... is starting to annoy me... you're also using google groups... it doesn't wrap paragraphs correctly... please read and action this https://wiki.python.org/moin/GoogleGroupsPython... it does wrap paragraphs correctly... it also prevents us seeing double line spacing... do you get my drift??? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-03-01 13:01 -0800 |
| Message-ID | <3ad31471-26ea-401d-a860-3604cf0e55b7@googlegroups.com> |
| In reply to | #67317 |
On Saturday, March 1, 2014 8:54:43 AM UTC-6, Mark Lawrence wrote: > you're also using google groups... it doesn't wrap paragraphs > > correctly... please read and action this > > https://wiki.python.org/moin/GoogleGroupsPython... it does wrap > > paragraphs correctly... it also prevents us seeing double line spacing... > > > > do you get my drift??? > hi Mark, yes, I understand. I am using google groups (for the moment) and it does not wrap correctly, at least not on my end. It also adds additional carrots > that make replying difficult. The elipses thing is a bad habit which I 'picked up' in academia lately. We use elipses frequently in papers (also this---which also annoys people) and there is no problem. In a writing context the elipses seem to function for some people (intentionally) as 'um'. When humans speak they use the word 'um' to pause between though context and its usually unintentional at the surface. Often when I write the elipses (...) show up for the same reason. I really don't know that I'm doing it... it just happens. So, I am working on it. No, you're not the first to mention it. Its one of my many flaws. Thanks for keeping me accountable. Enjoy the day! marcus
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-02-28 22:25 -0800 |
| Message-ID | <9ee137b0-3313-41c6-9792-9438ff05038a@googlegroups.com> |
| In reply to | #67291 |
On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote: > How would you propose doing that? Bear in mind that while Python > knows that tuples specifically are immutable, it doesn't generally > know whether a type is immutable. I was going to bed, and then thought of the solution. Allow the action. Hold the error pending until the action either succeeds or fails for the "item," in this case a list, and then post the error for the tuple depending... this would make the whole mess consistent, and even compatible with the idea of dynamic name and type binding... So, in other words, the action should be permitted, and actually was allowed, and the message is incorrectly reporting something that for this particular "item" is NOT true. The error message (and timing of same) is the bug (philosophically). Under the covers it may be (and probably is) more complicated. Good night everyone. Cheers
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-03-01 12:45 -0700 |
| Message-ID | <mailman.7531.1393703199.18130.python-list@python.org> |
| In reply to | #67298 |
On Fri, Feb 28, 2014 at 11:25 PM, Mark H. Harris <harrismh777@gmail.com> wrote:
> On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote:
>
>> How would you propose doing that? Bear in mind that while Python
>> knows that tuples specifically are immutable, it doesn't generally
>> know whether a type is immutable.
>
> I was going to bed, and then thought of the solution. Allow the action.
>
> Hold the error pending until the action either succeeds or fails for the "item," in this case a list, and then post the error for the tuple depending... this would make the whole mess consistent, and even compatible with the idea of dynamic name and type binding...
>
> So, in other words, the action should be permitted, and actually was allowed, and the message is incorrectly reporting something that for this particular "item" is NOT true. The error message (and timing of same) is the bug (philosophically).
>
> Under the covers it may be (and probably is) more complicated.
Indeed. For one thing, __iadd__ is not required to return the object
it was called on; it could return some other object. Imagine a
balanced binary tree that is stored by referencing the root node
object (whether this is good design is tangential; it's a possible
design). If the __iadd__ operator is implemented to insert a node,
and it causes the root node to change, then it might return that new
root node, expecting it to be assigned. If Python simply ignores the
exception from the assignment, then the data structure has been
modified in-place, but the tuple does not contain the correct object,
and worst of all no exception has been raised to alert anybody of this
failure condition. So at best you could only ignore these exceptions
when the object returned by __iadd__ is self, which to be fair is
probably most of the time.
Additionally, recall my statement up-thread that "If you skip the
assignment, and that assignment is meaningful to whatever the left
side may be (e.g. assigning to a descriptor or something that invokes
__setitem__ or __setattr__), then the operation is not equivalent."
If you quash the exception from the assignment because the __iadd__
call succeeded, then you have effectively skipped the assignment and
then lied to the programmer about it. For example, imagine a list
subclass that contains other lists but only permits itself to be
nested 1-deep; the contained lists are required to be flat. The
__setitem__ method for the class might enforce the constraint and
perhaps also update a count of the total combined length of the nested
lists. Then suppose we have this code:
lol = ListOfLists([1,2,3], [4], [6, 7, 8, 9])
lol[1] += [5, [5.25, 5.5, 5.75]]
The effect of this is that the middle sublist has been extended to
include a doubly-nested list. __setitem__ was then called, which
noticed that the list it was passed includes another nested list, so
it raised an exception instead of performing the assignment and
updating the count. The ListOfLists is now in an invalid state, but
if Python swallows the exception raised by __setitem__, then there is
nothing to warn the programmer of this (until something else
mysteriously fails to process the ListOfLists later on). The result
is code that is hard to debug.
Now, we might notice that the above code would probably not raise a
TypeError, which is the exception we would expect if trying to mutate
an immutable object, so we might revise the rule again: we only
silence the exception if __iadd__ returns self and the exception is a
TypeError. But even then, we have no guarantee that this is what the
TypeError was meant to convey. A TypeError may have simply propagated
up from other buggy code that was indirectly called by __setitem__, a
legitimate error that should be brought to the programmer's attention.
tldr: Swallowing exceptions is a risky practice unless you're quite
sure that you know where the exception is coming from and that it's
safe to ignore, and the language runtime should practically never do
this.
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-03-01 13:21 -0800 |
| Message-ID | <889d371a-c8e3-4d6b-8ba4-d3df61f29b0d@googlegroups.com> |
| In reply to | #67291 |
On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote:
> How would you propose doing that? Bear in mind that while Python
> knows that tuples specifically are immutable, it doesn't generally
> know whether a type is immutable.
hi Ian, I thought of something else after I slept on it, so to speak. Consider this:
>>> s=(2,3,[42,43,44],7)
>>> s[2]
[42, 43, 44]
>>>
s[2] is a list. We should be able to change s[2] even though its within a tuple, like the:
[42, 43, 44]
>>> s[2].append(45)
>>> s[2]
[42, 43, 44, 45] <===== no error
>>>
or like this:
>>> s[2]
[42, 43, 44, 45]
>>> s[2]=s[2]+[46]
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
s[2]=s[2]+[46] <==========error, but look below======
TypeError: 'tuple' object does not support item assignment
>>>
>>> s[2]
[42, 43, 44, 45] <=========also no change to list !!
>>>
The point I'm trying to make with this post is that s[2]+=[46] and s[2]=s[2]+[46] are handled inconsistently. In each case (whether the list is part of a tuple or not) s[2] is a valid list and should be mutable. In every case, in fact, it is. In each case, in fact, the change might occur. But, the change occurs in the first case (append) without an error. The change occurs in the next case too (+=) but with an error not related to the tuple. The change does not occur in the third case (s=s+ with an error) but the list is not changed !
We all know this is not good. We also all know that its because of implementation details the user/coder should not need to know. QED: a bug.
Having slept on it, I am remembering my Zen of Python: Errors should never pass silently, unless explicitly silenced. It looks to me like (+=) in this case is not being handled correctly under the covers. At any rate the three scenarios of trying to change a mutable list as an immutable tuple item should be handled consistently. Either we can change the tuple item (if its a list) or we can't. Also, if we cannot then the expected error should be consistent.
Wow. I think I got that whole thing out without one elipses.
Cheers
[toc] | [prev] | [next] | [standalone]
| From | Eric Jacoboni <eric.jacoboni@gmail.com> |
|---|---|
| Date | 2014-03-02 03:04 +0100 |
| Message-ID | <leu3jg$1gqu$1@cabale.usenet-fr.net> |
| In reply to | #67371 |
Le 01/03/2014 22:21, Mark H. Harris a écrit : > The point I'm trying to make with this post is that s[2]+=[46] and > s[2]=s[2]+[46] are handled inconsistently. For my own, the fact that, in Python, a_liste += e_elt gives a different result than a_list = a_list + e_elt is a big source of trouble... I don't really find a good reason to justify that : a_list += "spam" gives a valid result, when a_list = a_list + "spam" is not allowed. Why the former is like a_list.extend() in the first place ? (well, it's not exactly an extend() as extend returns None, not +=). And if both operations were equivalent, i think my initial question about tuples will be clear and the behavio(u)r would me more consistent for me : tu = (10, [10, 30]) tu[1] = tu[1] + [20] <-- Big mistake! TypeError: 'tuple' object does not support item assignment <-- ok tu (10, [10, 30]) <-- ok too... In fact, i think i'm gonna forget += on lists :)
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-03-01 18:28 -0800 |
| Message-ID | <a727bf16-9a42-4322-9f5d-90bc2a7dbfc4@googlegroups.com> |
| In reply to | #67402 |
On Saturday, March 1, 2014 8:04:32 PM UTC-6, Eric Jacoboni wrote: > > > In fact, i think i'm gonna forget += on lists :) hi Eric, well, that might be extreme, but you certainly want to avoid trying to change an immutable. Something you might want to consider is trying something like creating a new immutable. In the example we've been looking at I think I would change the tuple list item with an append(); however, you might try building a new tuple instead of trying to change an existing tuple item. I must admit that I would never have found this bug myself, because I don't try to change tuples (at all). Anyway, I'm glad you found it -- we all learn and that's the good news. Cheers
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-03-02 05:32 -0700 |
| Message-ID | <mailman.7572.1393763606.18130.python-list@python.org> |
| In reply to | #67402 |
On Sat, Mar 1, 2014 at 7:04 PM, Eric Jacoboni <eric.jacoboni@gmail.com> wrote:
> In fact, i think i'm gonna forget += on lists :)
Well, do what you want, but I think you're taking the wrong lesson
from this. Don't forget about using += on lists. Instead, forget
about using assignments, augmented or otherwise, on tuple elements.
Would you expect this to work?
tup = (1, 2, 3)
tup[1] += 42
I'm guessing probably not. So I have a hard time understanding why it
should be expected to work any differently when the tuple element
happens to be a list. The fact that the list is actually modified I
think is a distraction from the main point: the error indicates that
something illegal happened, not that nothing has changed. Assignments
just are not allowed on tuple elements, and it doesn't matter what
type they happen to be.
[toc] | [prev] | [next] | [standalone]
| From | Eric Jacoboni <eric.jacoboni@gmail.com> |
|---|---|
| Date | 2014-03-02 14:38 +0100 |
| Message-ID | <levc9c$2e9t$1@cabale.usenet-fr.net> |
| In reply to | #67432 |
Le 02/03/2014 13:32, Ian Kelly a écrit : > On Sat, Mar 1, 2014 at 7:04 PM, Eric Jacoboni <eric.jacoboni@gmail.com> wrote: >> In fact, i think i'm gonna forget += on lists :) > > Well, do what you want, but I think you're taking the wrong lesson > from this. Don't forget about using += on lists. Instead, forget > about using assignments, augmented or otherwise, on tuple elements. > Would you expect this to work? Well, the thing about += on lists that makes me forget it, like i said in my previous post, is that its behaviour is not consistent with +. Don't get me wrong: i don't expect that modifying a tuple element works. That's exactly my point: my initial question was, why it "half works : it should not work at all". I was thinking that += on lists worked like update() or extend() : modifying lists in place... It was my mistake So, yes, i still don't get the point using a += operation, which is not even consistent with the + operation (see my exemple on "spam" in my previous post). The + operator to return the modified list and the update() or extend() methods to do in place replacements are well enough for my present needs. Maybe, in the future, i will find a use case of += for lists which is not covered by others methods, though... Who knows? I don't doubt that Python designers have made this choice and this behavior for a good reason: i've just not get it yet.
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2014-03-02 14:05 +0000 |
| Message-ID | <mailman.7577.1393769155.18130.python-list@python.org> |
| In reply to | #67438 |
On 02/03/2014 13:38, Eric Jacoboni wrote: > Le 02/03/2014 13:32, Ian Kelly a écrit : >> On Sat, Mar 1, 2014 at 7:04 PM, Eric Jacoboni <eric.jacoboni@gmail.com> wrote: >>> In fact, i think i'm gonna forget += on lists :) >> >> Well, do what you want, but I think you're taking the wrong lesson >> from this. Don't forget about using += on lists. Instead, forget >> about using assignments, augmented or otherwise, on tuple elements. >> Would you expect this to work? > > Well, the thing about += on lists that makes me forget it, like i said > in my previous post, is that its behaviour is not consistent with +. The behaviour is consistent except when you try to modify a tuple. > > Don't get me wrong: i don't expect that modifying a tuple element works. > That's exactly my point: my initial question was, why it "half works : > it should not work at all". I was thinking that += on lists worked like > update() or extend() : modifying lists in place... It was my mistake I'd like to see you get update to work on a list. This shows how confused you are over this issue. > > So, yes, i still don't get the point using a += operation, which is not > even consistent with the + operation (see my exemple on "spam" in my > previous post). The + operator to return the modified list and the > update() or extend() methods to do in place replacements are well enough > for my present needs. Maybe, in the future, i will find a use case of += > for lists which is not covered by others methods, though... Who knows? I > don't doubt that Python designers have made this choice and this > behavior for a good reason: i've just not get it yet. > All of this comes about because of the known issue with tuples. Take them out of the equation and the behaviour of =, +=, extend and append is consistent. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
[toc] | [prev] | [next] | [standalone]
| From | Eric Jacoboni <eric.jacoboni@gmail.com> |
|---|---|
| Date | 2014-03-02 15:17 +0100 |
| Message-ID | <leveh7$2jh0$1@cabale.usenet-fr.net> |
| In reply to | #67439 |
Le 02/03/2014 15:05, Mark Lawrence a écrit : > The behaviour is consistent except when you try to modify a tuple. > Not in my opinion... li = [10, 30] li = li + "spam" --> TypeError: can only concatenate list (not "str") li += "spam" --> Ok So, not, that's not what i call consistent. And it's not related to tuples... > I'd like to see you get update to work on a list. This shows how > confused you are over this issue. Well, sorry, i wanted to write .append()
[toc] | [prev] | [next] | [standalone]
| From | "albert visser" <albert.visser@gmail.com> |
|---|---|
| Date | 2014-03-02 15:37 +0100 |
| Message-ID | <mailman.7581.1393771074.18130.python-list@python.org> |
| In reply to | #67441 |
On Sun, 02 Mar 2014 15:17:11 +0100, Eric Jacoboni <eric.jacoboni@gmail.com> wrote: > Le 02/03/2014 15:05, Mark Lawrence a écrit : > >> The behaviour is consistent except when you try to modify a tuple. >> > > Not in my opinion... > > li = [10, 30] > li = li + "spam" --> TypeError: can only concatenate list (not "str") > li += "spam" --> Ok > possibly because you expect += to take "spam" as a string, but have you looked at the result? In [1]: mylist = ['1', '2'] In [2]: mylist += 'spam' In [3]: mylist Out[3]: ['1', '2', 's', 'p', 'a', 'm'] consequently, try adding something that can not be interpreted as a sequence: In [4]: mylist += 3 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-782b544a29d1> in <module>() ----> 1 mylist += 3 TypeError: 'int' object is not iterable -- Vriendelijke groeten / Kind regards, Albert Visser Using Opera's mail client: http://www.opera.com/mail/
[toc] | [prev] | [next] | [standalone]
| From | "Mark H. Harris" <harrismh777@gmail.com> |
|---|---|
| Date | 2014-03-01 18:15 -0800 |
| Message-ID | <ee51bda4-6700-43b2-8e24-e32043164d25@googlegroups.com> |
| In reply to | #67371 |
On Saturday, March 1, 2014 3:21:44 PM UTC-6, Mark H. Harris wrote:
> On Friday, February 28, 2014 11:16:18 PM UTC-6, Ian wrote:
hi Ian, I thought of something else after I slept on it, so to speak.
Consider this:
>>> s=(2,3,[42,43,44],7)
>>> s[2]
[42, 43, 44]
>>>
s[2] is a list. We should be able to change s[2] even though its within a tuple,
like this:
[42, 43, 44]
>>> s[2].append(45)
>>> s[2]
[42, 43, 44, 45] <===== no error
>>>
or like this:
>>> s[2]
[42, 43, 44, 45]
>>> s[2]=s[2]+[46]
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
s[2]=s[2]+[46] <==========error, but look below======
TypeError: 'tuple' object does not support item assignment
>>>
>>> s[2]
[42, 43, 44, 45] <=========also no change to list !!
>>>
The point I'm trying to make with this post is that s[2]+=[46]
and s[2]=s[2]+[46] are handled inconsistently. In each case
(whether the list is part of a tuple or not) s[2] is a valid
list and should be mutable. In every case, in fact, it is.
In each case, in fact, the change might occur. But, the change
occurs in the first case (append) without an error. The change
occurs in the next case too (+=) but with an error not related
to the tuple. The change does not occur in the third case
(s=s+ with an error) but the list is not changed !
We all know this is not good. We also all know that its because
of implementation details the user/coder should not need to know.
QED: a bug.
Having slept on it, I am remembering my Zen of Python: Errors
should never pass silently, unless explicitly silenced. It looks
to me like (+=) in this case is not being handled correctly
under the covers. At any rate the three scenarios of trying to
change a mutable list as an immutable tuple item should be handled
consistently.
Either we can change the tuple item (if its a list) or we can't.
Also, if we cannot then the expected error should
be consistent.
Cheers
Hi , I'm experimenting a bit with TextWrangler and gg to see if I can
at least solve my double spacing and wrap problems with cut
a paste for the moment.
Looks ok?
Thanks
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.python
csiph-web