473,322 Members | 1,526 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

list in a tuple

Recently, I got into a debate on programming.reddit.com about
what should happen in the following case:
>>a = ([1], 2)
a[0] += [3]
Currently, Python raises an error *and* changes the first element of
the tuple. Now, this seems like something one would want to
change - why raise an error *and* execute the thing it
was complaining about? The discussion seems to have no end, and
that is why I'm posting here. I would like to know what is the opinion
of the people on this group... Am I really mistaking for thinking that
this is strange and unwanted behavior? Btw I understand *why* is this
happening, I just think it should change...
And here is the post that started this discussion:
http://filoxus.blogspot.com/2007/12/...ble.html#links

Thanks for your replies
Dec 24 '07 #1
11 2642
On Dec 24, 4:13*pm, montyphy...@gmail.com wrote:
Like I said, it is clear *why* this happens, what I
am concerned is if this what we *want* to happen, i.e.,
if the current situation is satisfying. Your mytuple class
would be something that resembles a solution, my question
is what the people on this group think about it.
I understand you said that in your original post, but you didn't
explain what you thought the reason was. I've provided an explanation
(which might not be perfect) for two reasons:
* I thought it would be useful to other people reading this thread.
* It gave a motivation for the 'mytuple' class.

I'm not sure what I think about it yet :)

--
Arnaud

Dec 24 '07 #2
On Dec 24, 8:22*am, montyphy...@gmail.com wrote:
Recently, I got into a debate on programming.reddit.com about
what should happen in the following case:
>a = ([1], 2)
a[0] += [3]

Currently, Python raises an error *and* changes the first element of
the tuple. Now, this seems like something one would want to
change - why raise an error *and* execute the thing it
was complaining about?
Yawn. Multiple actions have been combined into one line. The first
succeeds and the second fails.

If you need commit-rollback behaviors, specify them explicitly in a
try/except. My bet is that you'll figure-out that you didn't really
need that behavior to begin with. No use cluttering and slowing the
language for something like this -- Python is not SQL.
Raymond
Dec 25 '07 #3
On Mon, 24 Dec 2007 18:01:53 -0800, Raymond Hettinger wrote:
>Currently, Python raises an error *and* changes the first element of
the tuple. Now, this seems like something one would want to change -
why raise an error *and* execute the thing it was complaining about?

Yawn. Multiple actions have been combined into one line.
And this is a good idea?
The first succeeds and the second fails.
And this is a good idea?

Shouldn't the tuple assignment raise the exception BEFORE calling
__iadd__ on the item, instead of after?
If you need commit-rollback behaviors, specify them explicitly in a
try/except. My bet is that you'll figure-out that you didn't really
need that behavior to begin with. No use cluttering and slowing the
language for something like this -- Python is not SQL.
Who said anything about commit-rollbacks?

But even if Python is not SQL, operations that half-succeed are a PITA
whenever they can occur, because you end up having to code around them in
all sorts of complicated and ugly ways. Either that, or you end up with
odd corner cases hiding bugs.

I was never a big fan of augmented assignments. I think it goes against
the Python grain: it's an implied operation, using punctuation, for the
sole (?) benefit of saving a keystroke or three.

But I think this behaviour counts as a wart on the language, rather than
a bug.

--
Steven
Dec 26 '07 #4
On Dec 26, 1:08*am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
On Mon, 24 Dec 2007 18:01:53 -0800, Raymond Hettinger wrote:
[...]
The first succeeds and the second fails.

And this is a good idea?

Shouldn't the tuple assignment raise the exception BEFORE calling
__iadd__ on the item, instead of after?
If you look at the bytecode generated, this doesn't seem possible:
>>def f():
... a = ([1],)
... a[0] += [2]
...
>>import dis
dis.dis(f)
2 0 LOAD_CONST 1 (1)
3 BUILD_LIST 1
6 BUILD_TUPLE 1
9 STORE_FAST 0 (a)

3 12 LOAD_FAST 0 (a)
15 LOAD_CONST 2 (0)
18 DUP_TOPX 2
21 BINARY_SUBSCR
22 LOAD_CONST 3 (2)
25 BUILD_LIST 1
28 INPLACE_ADD
29 ROT_THREE
30 STORE_SUBSCR
31 LOAD_CONST 0 (None)
34 RETURN_VALUE

BINARY_SUBSCR puts a[0] on the stack, it has no way to know that a[0]
will be changed in place. To allow an exception to be thrown before
the in-place modification of a[0], there should be a new bytecode
instruction, say BINARY_SUBSCR_WITH_A_VIEW_TO_CHANGE_IN_PLACE, which
checks that the subscriptable object supports STORE_SUBSCR (;-).

[...]
I was never a big fan of augmented assignments. I think it goes against
the Python grain: it's an implied operation, using punctuation, for the
sole (?) benefit of saving a keystroke or three.

But I think this behaviour counts as a wart on the language, rather than
a bug.
Yes. I didn't realise this before you mentioned it, but the culprit
here seems to be the augmented assignment which acts differently on
mutable and immutable objects:

b = a # say a is immutable
a += c # equivalent to a = a + c
b is a # -False

b = a # Now say a is mutable
a += c # equivalent to a.__iadd__(c)
b is a # -True

OTOH augmented assignent are a slight optimisation:

a[i] += 1

will look for the value of a and i only once and duplicate them on the
stack, whereas

a[i] = a[i] + 1

will need to resolve a and i twice (which can be costly if a and i are
globals)

--
Arnaud

Dec 26 '07 #5
After some tought I must agree that this is a wart more than
a bug and that it will probably be best not to mess with it.
However, what do you guys think about the print wart in Py3k
described at http://filoxus.blogspot.com/2007/12/...ble.html#links
(im not trying to advertise my blog, I just don't feel like
typing the whole problem all over again)?

On 26 pro, 19:11, Arnaud Delobelle <arno...@googlemail.comwrote:
On Dec 26, 1:08*am, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.auwrote:
On Mon, 24 Dec 2007 18:01:53 -0800, Raymond Hettinger wrote:
[...]
The first succeeds and the second fails.
And this is a good idea?
Shouldn't the tuple assignment raise the exception BEFORE calling
__iadd__ on the item, instead of after?

If you look at the bytecode generated, this doesn't seem possible:
>def f():

... * * a = ([1],)
... * * a[0] += [2]
...>>import dis
>dis.dis(f)

* 2 * * * * * 0 LOAD_CONST * * * * * * * 1 (1)
* * * * * * * 3 BUILD_LIST * * * * * * * 1
* * * * * * * 6 BUILD_TUPLE * * * * * * *1
* * * * * * * 9 STORE_FAST * * * * * * * 0 (a)

* 3 * * * * *12 LOAD_FAST * * * * * * * *0 (a)
* * * * * * *15 LOAD_CONST * * * * * * * 2 (0)
* * * * * * *18 DUP_TOPX * * * * * * * * 2
* * * * * * *21 BINARY_SUBSCR
* * * * * * *22 LOAD_CONST * * * * * * * 3 (2)
* * * * * * *25 BUILD_LIST * * * * * * * 1
* * * * * * *28 INPLACE_ADD
* * * * * * *29 ROT_THREE
* * * * * * *30 STORE_SUBSCR
* * * * * * *31 LOAD_CONST * * * * * * * 0 (None)
* * * * * * *34 RETURN_VALUE

BINARY_SUBSCR puts a[0] on the stack, it has no way to know that a[0]
will be changed in place. *To allow an exception to be thrown before
the in-place modification of a[0], there should be a new bytecode
instruction, say BINARY_SUBSCR_WITH_A_VIEW_TO_CHANGE_IN_PLACE, which
checks that the subscriptable object supports STORE_SUBSCR (;-).

[...]
I was never a big fan of augmented assignments. I think it goes against
the Python grain: it's an implied operation, using punctuation, for the
sole (?) benefit of saving a keystroke or three.
But I think this behaviour counts as a wart on the language, rather than
a bug.

Yes. *I didn't realise this before you mentioned it, but the culprit
here seems to be the augmented assignment which acts differently on
mutable and immutable objects:

b = a *# say a is immutable
a += c # equivalent to a = a + c
b is a # -False

b = a *# Now say a is mutable
a += c # equivalent to a.__iadd__(c)
b is a # -True

OTOH augmented assignent are a slight optimisation:

a[i] += 1

will look for the value of a and i only once and duplicate them on the
stack, whereas

a[i] = a[i] + 1

will need to resolve a and i twice (which can be costly if a and i are
globals)

--
Arnaud
Dec 27 '07 #6
Subject: Re: list in a tuple
To:
Cc:
Bcc:
Reply-To:
Newsgroup: comp.lang.python
-=-=-=-=-=-=-=-=-=# Don't remove this line #=-=-=-=-=-=-=-=-=-
mo*********@gmail.com wrote:
After some tought I must agree that this is a wart more than
a bug and that it will probably be best not to mess with it.
However, what do you guys think about the print wart in Py3k
described at
http://filoxus.blogspot.com/2007/12/...ble.html#links
(im not trying to advertise my blog, I just don't feel like
typing the whole problem all over again)?
From that post:
Ok, I do admit that doing

a = ([1], 2)
a[0].append(2)

also doesn't throw an error, but this only confuses me more.
Why? You mutate the list, but the tuple does not change. It is still a
tuple of a list and an int. At least that's how I think about it, and I
seem to recall reading that beavior justified like this (don't ask me
where though (might have been "Dive Into Python", but maybe not)).

/W
Dec 27 '07 #7


On Dec 27, 8:20 pm, Wildemar Wildenburger
<lasses_w...@klapptsowieso.netwrote:
>

From that post:
Ok, I do admit that doing
>
a = ([1], 2)
a[0].append(2)
>
also doesn't throw an error, but this only confuses me more.
>
Why? You mutate thelist, but thetupledoes not change. It is still atupleof alistand an int. At least that's how I think about it, and I
seem to recall reading that beavior justified like this (don't ask me
where though (might have been "Dive Into Python", but maybe not)).
That part is ok, I mean it doesn't confuse me I just wanted to say
that this is somewhat confusing behavior.
I agree that its not best put... But I was thinking about the last
part of the post, the part
that talks about trying to print a tuple and getting an error.
Dec 27 '07 #8
On Dec 27, 12:38 pm, montyphy...@gmail.com wrote:
After some tought I must agree that this is a wart more than
a bug and that it will probably be best not to mess with it.
However, what do you guys think about the print wart in Py3k
described athttp://filoxus.blogspot.com/2007/12/python-3000-how-mutable-is-immuta...
(im not trying to advertise my blog, I just don't feel like
typing the whole problem all over again)?

1. Tuples are immutable. None of the tuples in your example were
modified.

The behavior you want (which is not immutability of tuples, which
Python already has, but *recursive* immutability of all objects
contained within the tuple) is not an unreasonable thing to ask for,
but the design of Python and common usage of tuples makes it all but
impossible at this point.

There is no general way to determine whether an object is mutable or
not. (Python would have to add this capability, an extremely
substantial change, to grant your wish. It won't happen.)

Tuples are used internally to represent the arguments of a function,
which are often mutable.

Tuples are sometimes used to return multiple values from a function,
which could include mutable values.

Tuples are used to specify multiple arguments to a format string, some
of which could be mutable, though I guess this is going away in Python
3.
2. The issue with print in your example is a bug, not a wart. It'll
be fixed.

(This is just a guess, but I think it might have something to do with
the flux of the new bytes type. The behavior manifested itself when
trying to print a self-referencing structure probably only because
that section of code was lagging behind.)
3. You're still top posting, which goes against this group's
conventions and annoys quite a few people. When you reply to a
message, please move your cursor to below the quoted message before
you begin typing. Thank you
Carl Banks
Dec 27 '07 #9
Carl Banks wrote:
On Dec 27, 12:38 pm, montyphy...@gmail.com wrote:
>After some tought I must agree that this is a wart more than
a bug and that it will probably be best not to mess with it.
However, what do you guys think about the print wart in Py3k
described athttp://filoxus.blogspot.com/2007/12/python-3000-how-mutable-is-immuta...
(im not trying to advertise my blog, I just don't feel like
typing the whole problem all over again)?


1. Tuples are immutable. None of the tuples in your example were
modified.

The behavior you want (which is not immutability of tuples, which
Python already has, but *recursive* immutability of all objects
contained within the tuple) is not an unreasonable thing to ask for,
but the design of Python and common usage of tuples makes it all but
impossible at this point.

There is no general way to determine whether an object is mutable or
not. (Python would have to add this capability, an extremely
substantial change, to grant your wish. It won't happen.)
like I said, I don't think that this behavior should be changed...
therefore, no wish-granting is needed, thank you :)

>
Tuples are used internally to represent the arguments of a function,
which are often mutable.

Tuples are sometimes used to return multiple values from a function,
which could include mutable values.

Tuples are used to specify multiple arguments to a format string, some
of which could be mutable, though I guess this is going away in Python
3.
2. The issue with print in your example is a bug, not a wart. It'll
be fixed.

(This is just a guess, but I think it might have something to do with
the flux of the new bytes type. The behavior manifested itself when
trying to print a self-referencing structure probably only because
that section of code was lagging behind.)
3. You're still top posting, which goes against this group's
conventions and annoys quite a few people. When you reply to a
message, please move your cursor to below the quoted message before
you begin typing. Thank you
sorry for top posting...
Dec 27 '07 #10
En Thu, 27 Dec 2007 16:38:07 -0300, <mo*********@gmail.comescribió:
On Dec 27, 8:20 pm, Wildemar Wildenburger
<lasses_w...@klapptsowieso.netwrote:
> >

From that post:
> Ok, I do admit that doing

a = ([1], 2)
a[0].append(2)

also doesn't throw an error, but this only confuses me more.
Why? You mutate thelist, but thetupledoes not change. It is still
atupleof alistand an int. At least that's how I think about it, and I
seem to recall reading that beavior justified like this (don't ask me
where though (might have been "Dive Into Python", but maybe not)).

That part is ok, I mean it doesn't confuse me I just wanted to say
that this is somewhat confusing behavior.
I agree that its not best put... But I was thinking about the last
part of the post, the part
that talks about trying to print a tuple and getting an error.
Instead of trying to explain it myself, I'll refer you to this little
essay [1] by Michael Hudson including some nice ASCII art, and a long
reply from Alex Martelli from which I'll quote just a few memorable
paragraphs. (Just replace "dictionary" with "tuple" in your example)

"""There is [...] a huge difference
between changing an object, and changing (mutating) some
OTHER object to which the first refers.

In Bologna over 100 years ago we had a statue of a local hero
depicted pointing forwards with his finger -- presumably to
the future, but given where exactly it was placed, the locals
soon identified it as "the statue that points to Hotel
Belfiore". The one day some enterprising developer bought
the hotel's building and restructured it -- in particular,
where the hotel used to be was now a restaurant, Da Carlo.

So, "the statue that points to Hotel Belfiore" had suddenly
become "the statue that points to Da Carlo"...! Amazing
isn't it? Considering that marble isn't very fluid and the
statue had not been moved or disturbed in any way...?

This is a real anecdote, by the way (except that I'm not
sure of the names of the hotel and restaurant involved --
I could be wrong on those), but I think it can still help
here. The dictionary, or statue, has not changed at all,
even though the objects it refers/points to may have been
mutated beyond recognition, and the name people know it
by (the dictionary's string-representation) may therefore
change. That name or representation was and is referring
to a non-intrinsic, non-persistent, "happenstance"
characteristic of the statue, or dictionary...
"""

[1] http://python.net/crew/mwh/hacks/objectthink.html

--
Gabriel Genellina

Dec 28 '07 #11
On Dec 28, 1:34 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Thu, 27 Dec 2007 16:38:07 -0300, <montyphy...@gmail.comescribió:
On Dec 27, 8:20 pm, Wildemar Wildenburger
<lasses_w...@klapptsowieso.netwrote:
From that post:
Ok, I do admit that doing
a = ([1], 2)
a[0].append(2)
also doesn't throw an error, but this only confuses me more.
Why? You mutate thelist, but thetupledoes not change. It is still
atupleof alistand an int. At least that's how I think about it, and I
seem to recall reading that beavior justified like this (don't ask me
where though (might have been "Dive Into Python", but maybe not)).
That part is ok, I mean it doesn't confuse me I just wanted to say
that this is somewhat confusing behavior.
I agree that its not best put... But I was thinking about the last
part of the post, the part
that talks about trying to print a tuple and getting an error.

Instead of trying to explain it myself, I'll refer you to this little
essay [1] by Michael Hudson including some nice ASCII art, and a long
reply from Alex Martelli from which I'll quote just a few memorable
paragraphs. (Just replace "dictionary" with "tuple" in your example)

"""There is [...] a huge difference
between changing an object, and changing (mutating) some
OTHER object to which the first refers.

In Bologna over 100 years ago we had a statue of a local hero
depicted pointing forwards with his finger -- presumably to
the future, but given where exactly it was placed, the locals
soon identified it as "the statue that points to Hotel
Belfiore". The one day some enterprising developer bought
the hotel's building and restructured it -- in particular,
where the hotel used to be was now a restaurant, Da Carlo.

So, "the statue that points to Hotel Belfiore" had suddenly
become "the statue that points to Da Carlo"...! Amazing
isn't it? Considering that marble isn't very fluid and the
statue had not been moved or disturbed in any way...?

This is a real anecdote, by the way (except that I'm not
sure of the names of the hotel and restaurant involved --
I could be wrong on those), but I think it can still help
here. The dictionary, or statue, has not changed at all,
even though the objects it refers/points to may have been
mutated beyond recognition, and the name people know it
by (the dictionary's string-representation) may therefore
change. That name or representation was and is referring
to a non-intrinsic, non-persistent, "happenstance"
characteristic of the statue, or dictionary...
"""

[1]http://python.net/crew/mwh/hacks/objectthink.html

--
Gabriel Genellina
Thank you very much for this discussion and reference [1] and other
pointers in [1]. This has definitely helped my understanding of such
matters.
Dec 28 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Fuzzyman | last post by:
Pythons internal 'pointers' system is certainly causing me a few headaches..... When I want to copy the contents of a variable I find it impossible to know whether I've copied the contents *or*...
9
by: Yomanium Yoth Taripoät II | last post by:
HI, 1) what are the differences between list and tuple? 2) how to concatenate tuple and list? no method, no opérator? 3) im looking the fucking manual, and cant add value in my tuple, when it...
4
by: GrelEns | last post by:
hello, i wonder if this possible to subclass a list or a tuple and add more attributes ? also does someone have a link to how well define is own iterable object ? what i was expecting was...
2
by: Ishwar Rattan | last post by:
I am a little confused about a list and a tuple. Both can have dissimilar data-type elements, can be returned by functions. The only difference that I see is that list is mutable and tuple is...
16
by: flyaflya | last post by:
a = "(1,2,3)" I want convert a to tuple:(1,2,3),but tuple(a) return ('(', '1', ',', '2', ',', '3', ')') not (1,2,3)
5
by: Xah Lee | last post by:
suppose i'm going to have a data structure like this: , , , , .... ] should i use (width,height) or ?
6
by: fdu.xiaojf | last post by:
Hi all, I can use list comprehension to create list quickly. So I expected that I can created tuple quickly with the same syntax. But I found that the same syntax will get a generator, not a...
25
by: beginner | last post by:
Hi, I am wondering how do I 'flatten' a list or a tuple? For example, I'd like to transform or ] to . Another question is how do I pass a tuple or list of all the aurgements of a function to...
3
by: Davy | last post by:
Hi all, I am curious about whether there is function to fransform pure List to pure Tuple and pure Tuple to pure List? For example, I have list L = ,] something list2tuple() will have...
0
by: Hatem Nassrat | last post by:
on Wed Jun 13 10:17:24 CEST 2007, Diez B. Roggisch deets at nospam.web.de wrote: Well I have looked into this and it seems that using the list comprehension is faster, which is...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.