473,379 Members | 1,144 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,379 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 2644
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...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.