Re: How to extend a tuple of tuples?
John Gordon wrote: > […] Thomas 'PointedEars' Lahn […] writes: It is supposed to be an attribution *line*, _not_ an attribution novel. >> >> The obvious way does not work - >> >> >> >> a += (5, 6) >> ^^ >> > Right, because a tuple is immutable. > >> How did you get that idea? It has been mutated in the very statement >> that you are quoting > > No. An entirely new tuple is created, and 'a' is rebound to it. The > existing tuple is not mutated. Indeed, | $ python3 | Python 3.4.4 (default, Apr 17 2016, 16:02:33) | [GCC 5.3.1 20160409] on linux | Type "help", "copyright", "credits" or "license" for more information. | >>> t = ((1, 2), (3, 4)) | >>> t.__repr__ | | >>> t += (5, 6), | >>> t.__repr__ | indicates that this is so. However, this argument is purely academic, as that rebinding happens would neither validate Ben’s argument nor invalidate mine: The result obtained without the trailing comma is not so “because a tuple is immutable”, but because of how the expression RHS is parsed. -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Mon, Sep 12, 2016, at 17:29, Chris Angelico wrote: > old_id = id(a) > a += something > if id(a) == old_id: > print("We may have an optimization, folks!") > > But that can have false positives. If two objects do not concurrently > exist, they're allowed to have the same ID number. But the two objects do concurrently exist, from the time __iadd__ is evaluated until the time when a is assigned, in the formal semantics of this code. Allowing them to not concurrently exist is, effectively, precisely the optimization being discussed. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
Am 13.09.2016 um 12:09 schrieb Chris Angelico: On Tue, Sep 13, 2016 at 8:01 PM, Antoon Pardon wrote: Then python seems to be broken: ]]] a = range(3) ]]] old_a = a ]]] a += [8, 13] ]]] id(a), id(old_a) (140062018784792, 140062018784792) ]]] a, old_a ([0, 1, 2, 8, 13], [0, 1, 2, 8, 13]) A range object is not a tuple. Nor (since you were probably running this in Python 2) is a list. Not probably, certainly (if it wasn't Python 1): Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> a = range(3) >>> a += [8, 13] Traceback (most recent call last): File "", line 1, in a += [8, 13] TypeError: unsupported operand type(s) for +=: 'range' and 'list' >>> -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Tue, Sep 13, 2016 at 8:01 PM, Antoon Pardon wrote: >>> You could do the following: >>> >>> old_a = a >>> a += something >>> if old_a is a: >>> print("We have an optimization, folks!") >>> >> Uhm... that defeats the whole point of it being an optimization. See >> above, "there are no other references to it". :) > > What do you mean? If it is an optimization, then the object a refers to > will be mutated, whether or not there are other references. These other > reference will all still refer to the same object that is now mutated. The language spec says that tuples are immutable. If there's an optimization, it is pretending that the tuple is immutable if and only if there are no other references to that object. But old_a is another reference to that object! > So how does my example defeats the point of it being an optimization? > >> If this condition is ever true, Python's language spec has been violated. >> > Then python seems to be broken: > > ]]] a = range(3) > ]]] old_a = a > ]]] a += [8, 13] > ]]] id(a), id(old_a) > (140062018784792, 140062018784792) > ]]] a, old_a > ([0, 1, 2, 8, 13], [0, 1, 2, 8, 13]) A range object is not a tuple. Nor (since you were probably running this in Python 2) is a list. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
Op 13-09-16 om 11:27 schreef Chris Angelico: > On Tue, Sep 13, 2016 at 5:25 PM, Antoon Pardon > wrote: >> Op 12-09-16 om 23:29 schreef Chris Angelico: >>> On Tue, Sep 13, 2016 at 7:19 AM, BartC wrote: By the same argument, then strings and ints are also mutable. Here, the original tuple that a refers to has been /replaced/ by a new one. The original is unchanged. (Unless, by some optimisation that recognises that there are no other references to it, the original is actually appended to. But in general, new objects are constructed when implementing +=.) >>> And by definition, that optimization cannot be detected. At best, all >>> you could do is something like: >>> >>> old_id = id(a) >>> a += something >>> if id(a) == old_id: >>> print("We may have an optimization, folks!") >>> >>> But that can have false positives. If two objects do not concurrently >>> exist, they're allowed to have the same ID number. >> You could do the following: >> >> old_a = a >> a += something >> if old_a is a: >> print("We have an optimization, folks!") >> > Uhm... that defeats the whole point of it being an optimization. See > above, "there are no other references to it". :) What do you mean? If it is an optimization, then the object a refers to will be mutated, whether or not there are other references. These other reference will all still refer to the same object that is now mutated. So how does my example defeats the point of it being an optimization? > If this condition is ever true, Python's language spec has been violated. > Then python seems to be broken: ]]] a = range(3) ]]] old_a = a ]]] a += [8, 13] ]]] id(a), id(old_a) (140062018784792, 140062018784792) ]]] a, old_a ([0, 1, 2, 8, 13], [0, 1, 2, 8, 13]) -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Tue, Sep 13, 2016 at 5:25 PM, Antoon Pardon wrote: > Op 12-09-16 om 23:29 schreef Chris Angelico: >> On Tue, Sep 13, 2016 at 7:19 AM, BartC wrote: >>> By the same argument, then strings and ints are also mutable. >>> >>> Here, the original tuple that a refers to has been /replaced/ by a new one. >>> The original is unchanged. (Unless, by some optimisation that recognises >>> that there are no other references to it, the original is actually appended >>> to. But in general, new objects are constructed when implementing +=.) >> And by definition, that optimization cannot be detected. At best, all >> you could do is something like: >> >> old_id = id(a) >> a += something >> if id(a) == old_id: >> print("We may have an optimization, folks!") >> >> But that can have false positives. If two objects do not concurrently >> exist, they're allowed to have the same ID number. > > You could do the following: > > old_a = a > a += something > if old_a is a: > print("We have an optimization, folks!") > Uhm... that defeats the whole point of it being an optimization. See above, "there are no other references to it". :) If this condition is ever true, Python's language spec has been violated. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
Op 12-09-16 om 23:29 schreef Chris Angelico: > On Tue, Sep 13, 2016 at 7:19 AM, BartC wrote: >> By the same argument, then strings and ints are also mutable. >> >> Here, the original tuple that a refers to has been /replaced/ by a new one. >> The original is unchanged. (Unless, by some optimisation that recognises >> that there are no other references to it, the original is actually appended >> to. But in general, new objects are constructed when implementing +=.) > And by definition, that optimization cannot be detected. At best, all > you could do is something like: > > old_id = id(a) > a += something > if id(a) == old_id: > print("We may have an optimization, folks!") > > But that can have false positives. If two objects do not concurrently > exist, they're allowed to have the same ID number. You could do the following: old_a = a a += something if old_a is a: print("We have an optimization, folks!") -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Monday, September 12, 2016 at 4:31:37 PM UTC-4, Thomas 'PointedEars' Lahn wrote: > Ben Finney wrote: > > So instead, you want a different tuple. You do that by creating it, > > explicitly constructing a new sequence with the items you want:: > > > > b = tuple([ > > item for item in a > > ] + [(5, 6)]) > > The correct approach is > > | >>> a += (5, 6), > | >>> a > | ((1, 2), (3, 4), (5, 6)) > > The problem here is an ambiguity in the Python grammar where “(5, 6)” is > _not_ parsed as a double, but as a list of singles. The ambiguity is > resolved by adding a trailing comma. There is no ambiguity in "(5, 6)". It is a tuple of two ints. To make a sequence of tuples (albeit a one-element sequence), you add a comma to make it a one-element tuple, which is the same as "((5,6),)". > (This is basic Python knowledge.) Considering the gaps in your own Python knowledge, please try not to be condescending when answering questions here. For a discussion of mutability and immutability in Python, which will help with the other part of the discussion, you might like: http://nedbatchelder.com/text/names1.html --Ned. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Tue, Sep 13, 2016 at 7:19 AM, BartC wrote: > By the same argument, then strings and ints are also mutable. > > Here, the original tuple that a refers to has been /replaced/ by a new one. > The original is unchanged. (Unless, by some optimisation that recognises > that there are no other references to it, the original is actually appended > to. But in general, new objects are constructed when implementing +=.) And by definition, that optimization cannot be detected. At best, all you could do is something like: old_id = id(a) a += something if id(a) == old_id: print("We may have an optimization, folks!") But that can have false positives. If two objects do not concurrently exist, they're allowed to have the same ID number. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On 12/09/2016 21:31, Thomas 'PointedEars' Lahn wrote: Ben Finney wrote: "Frank Millman" writes: Assume you have a tuple of tuples - a = ((1, 2), (3, 4)) You want to add a new tuple to it, so that it becomes As you acknowledge, the tuple ‘a’ can't become anything else. Instead, you need to create a different value. Wrong. The obvious way does not work - a += (5, 6) ((1, 2), (3, 4), 5, 6) ^^ Right, because a tuple is immutable. How did you get that idea? It has been mutated in the very statement that you are quoting, By the same argument, then strings and ints are also mutable. Here, the original tuple that a refers to has been /replaced/ by a new one. The original is unchanged. (Unless, by some optimisation that recognises that there are no other references to it, the original is actually appended to. But in general, new objects are constructed when implementing +=.) -- Bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
In <2349538.mvxudi8...@pointedears.de> Thomas 'PointedEars' Lahn writes: > >> The obvious way does not work - > >> > >> a += (5, 6) > ^^ > > Right, because a tuple is immutable. > How did you get that idea? It has been mutated in the very statement that > you are quoting No. An entirely new tuple is created, and 'a' is rebound to it. The existing tuple is not mutated. -- John Gordon A is for Amy, who fell down the stairs gor...@panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Saturday, September 10, 2016 at 12:21:48 AM UTC+12, Frank Millman wrote: > The short answer is that I am using it as a dictionary key. Another option is, if it takes several steps to construct the tuple, to build it incrementally as a list and then cast it to a tuple. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Friday, September 9, 2016 at 5:58:16 PM UTC+5:30, Chris Angelico wrote: > On Fri, Sep 9, 2016 at 10:21 PM, Frank Millman wrote: > > I am building a series of JOINs for a SQL statement. Some of them can be > > nested - table A is joined from table B is joined from table C. In other > > parts of the same SQL statement, table A could be joined from table D which > > is joined from table E. > > > > For each potential candidate, I need to check if I have already built the > > JOIN. If so, just use it. If not, build it, and update a dictionary to > > indicate that it has been built. > > > > The key to the dictionary is the path to the joined table, which could be > > several levels deep. I build up a tuple to represent the path. Each table > > needs two pieces of information to identify it, so I use a tuple for each > > identifier. > > > > The value portion of the dictionary is simply the alias generated for the > > joined table. I use the alias in the body of the SQL statement. > > Sounds fair enough. A tuple is a pretty reasonable way to do this. > > The other approach would be to craft the aliases directly, as strings. > For instance, your first example could be JOIN_A_B_C, and your second > JOIN_A_D_E. (Sort the table names alphabetically before "_".join()ing > them if you want order to be insignificant.) If the requirement is to have ('A', 'B') == ('B', 'A') the correct data structure to use is set(['A','B']) In this case frozenset for immutability or allowed-for-dict-key requirements [Disclaimer: Ive never used it like this so dont know rough edges; just talking ‘theoretically’!!] -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Fri, Sep 9, 2016 at 10:21 PM, Frank Millman wrote: > I am building a series of JOINs for a SQL statement. Some of them can be > nested - table A is joined from table B is joined from table C. In other > parts of the same SQL statement, table A could be joined from table D which > is joined from table E. > > For each potential candidate, I need to check if I have already built the > JOIN. If so, just use it. If not, build it, and update a dictionary to > indicate that it has been built. > > The key to the dictionary is the path to the joined table, which could be > several levels deep. I build up a tuple to represent the path. Each table > needs two pieces of information to identify it, so I use a tuple for each > identifier. > > The value portion of the dictionary is simply the alias generated for the > joined table. I use the alias in the body of the SQL statement. Sounds fair enough. A tuple is a pretty reasonable way to do this. The other approach would be to craft the aliases directly, as strings. For instance, your first example could be JOIN_A_B_C, and your second JOIN_A_D_E. (Sort the table names alphabetically before "_".join()ing them if you want order to be insignificant.) Obviously this won't do if it runs the risk of crashing into length limits in your SQL engine, but if you find tuples too annoying, this is an equally valid way of crafting the keys for your dictionary. Overall, this sounds like one of those horrendously messy pieces of code that exists because... it's dealing with a horrendously messy situation. Which, sad to say, happens all too often in real-world code, much as we'd love to pretend it doesn't in examples on mailing lists :| ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
"Ned Batchelder" wrote in message news:44e067ce-f499-4ca8-87bd-94b18dfc0...@googlegroups.com... On Friday, September 9, 2016 at 6:13:37 AM UTC-4, Frank Millman wrote: > "Frank Millman" wrote in message news:nqtlue$unj$1...@blaine.gmane.org... > > The one I was looking for was > > a += (5, 6), > > I understand it now - makes perfect sense. I'm curious why you are using a growing tuple, instead of a list. This seems like a much more natural use for a list. The short answer is that I am using it as a dictionary key. However, from The Zen of Python - If the implementation is hard to explain, it's a bad idea. Let's see if I can explain. I am building a series of JOINs for a SQL statement. Some of them can be nested - table A is joined from table B is joined from table C. In other parts of the same SQL statement, table A could be joined from table D which is joined from table E. For each potential candidate, I need to check if I have already built the JOIN. If so, just use it. If not, build it, and update a dictionary to indicate that it has been built. The key to the dictionary is the path to the joined table, which could be several levels deep. I build up a tuple to represent the path. Each table needs two pieces of information to identify it, so I use a tuple for each identifier. The value portion of the dictionary is simply the alias generated for the joined table. I use the alias in the body of the SQL statement. I don't know if that explains it very well. I can supply more info if anyone is curious, or wishes to suggest a better approach. Frank -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Friday, September 9, 2016 at 6:13:37 AM UTC-4, Frank Millman wrote: > "Frank Millman" wrote in message news:nqtlue$unj$1...@blaine.gmane.org... > > > Assume you have a tuple of tuples - > > > a = ((1, 2), (3, 4)) > > > You want to add a new tuple to it, so that it becomes - > > > ((1, 2), (3, 4), (5, 6)) > > Thanks all. > > The one I was looking for was > > a += (5, 6), > > I understand it now - makes perfect sense. I'm curious why you are using a growing tuple, instead of a list. This seems like a much more natural use for a list. --Ned. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
"Frank Millman" wrote in message news:nqtlue$unj$1...@blaine.gmane.org... Assume you have a tuple of tuples - a = ((1, 2), (3, 4)) You want to add a new tuple to it, so that it becomes - ((1, 2), (3, 4), (5, 6)) Thanks all. The one I was looking for was a += (5, 6), I understand it now - makes perfect sense. Frank -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Fri, 9 Sep 2016 04:47 pm, Frank Millman wrote: > Hi all > > This should be easy, but I cannot figure it out. > > Assume you have a tuple of tuples - > > a = ((1, 2), (3, 4)) > > You want to add a new tuple to it, so that it becomes - > > ((1, 2), (3, 4), (5, 6)) a = a + ((5, 6),) You might think that you can just add (5, 6) but that doesn't work: py> a + (5, 6) ((1, 2), (3, 4), 5, 6) The plus operator builds a new tuple containing the contents of each of the two tuples concatenated, so to get the result that you want you need a tuple containing (5, 6) as the one and only item. Because that's a tuple with one item, you need a trailing comma: py> len( ((5, 6),) ) 1 py> a + ((5, 6),) ((1, 2), (3, 4), (5, 6)) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
Ben Finney writes: > Frank Millman writes: > >> Assume you have a tuple of tuples - >> >> a = ((1, 2), (3, 4)) >> >> You want to add a new tuple to it, so that it becomes > > As you acknowledge, the tuple ‘a’ can't become anything else. Instead, > you need to create a different value. > >> The obvious way does not work - >> >> a += (5, 6) >> >>((1, 2), (3, 4), 5, 6) > > Right, because a tuple is immutable. > > So instead, you want a different tuple. You do that by creating it, > explicitly constructing a new sequence with the items you want:: > > b = tuple([ > item for item in a > ] + [(5, 6)]) b = tuple(list(a) + [(5,6)]) b = a + tuple([(5,6)]) b = a + ((5,6),) b = tuple(itertools.chain(iter(a), iter(((5,6), # : -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
"Frank Millman" writes: > Assume you have a tuple of tuples - > > a = ((1, 2), (3, 4)) > > You want to add a new tuple to it, so that it becomes As you acknowledge, the tuple ‘a’ can't become anything else. Instead, you need to create a different value. > The obvious way does not work - > > a += (5, 6) > >((1, 2), (3, 4), 5, 6) Right, because a tuple is immutable. So instead, you want a different tuple. You do that by creating it, explicitly constructing a new sequence with the items you want:: b = tuple([ item for item in a ] + [(5, 6)]) -- \“Look at it this way: Think of how stupid the average person | `\ is, and then realise half of 'em are stupider than that.” | _o__) —George Carlin, _Doin' It Again_, 1990 | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
On Friday, September 9, 2016 at 12:18:24 PM UTC+5:30, Frank Millman wrote: > Hi all > > This should be easy, but I cannot figure it out. > > Assume you have a tuple of tuples - > > a = ((1, 2), (3, 4)) > > You want to add a new tuple to it, so that it becomes - > > ((1, 2), (3, 4), (5, 6)) Your example does not add inside the inner tuples So I am simplifying the question to > Assume you have a tuple of tuples - > > a = (1 2 3) > > You want to add a new element to it, so that it becomes - > > (1 2 3 4) >>> t = (1,2,3) >>> new = t + (4,) >>> new (1, 2, 3, 4) >>> Slightly harder if the new addition were inbetween >>> t = (1,2,3) >>> t[:1] (1,) >>> t[1:] (2, 3) >>> t[:1] + (42,) + t[1:] (1, 42, 2, 3) -- https://mail.python.org/mailman/listinfo/python-list
Re: How to extend a tuple of tuples?
"Frank Millman" writes: > Hi all > > This should be easy, but I cannot figure it out. > > Assume you have a tuple of tuples - > > a = ((1, 2), (3, 4)) > > You want to add a new tuple to it, so that it becomes - > >((1, 2), (3, 4), (5, 6)) > > The obvious way does not work - > > a += (5, 6) > >((1, 2), (3, 4), 5, 6) You could use: a += (5, 6), or (more clearly written): a += ((5, 6),) -- https://mail.python.org/mailman/listinfo/python-list
How to extend a tuple of tuples?
Hi all This should be easy, but I cannot figure it out. Assume you have a tuple of tuples - a = ((1, 2), (3, 4)) You want to add a new tuple to it, so that it becomes - ((1, 2), (3, 4), (5, 6)) The obvious way does not work - a += (5, 6) ((1, 2), (3, 4), 5, 6) I have discovered that there is something new in python 3.5 that does work - a = (*a, (5, 6)) ((1, 2), (3, 4), (5, 6)) But how would you have done it before? I know you can convert the outer tuple to a list, add the new tuple, and convert it back again. Is that the only solution? BTW, I do know that tuples are immutable, and that all of the above operations create a new tuple. Frank Millman -- https://mail.python.org/mailman/listinfo/python-list