Re: How to extend a tuple of tuples?

2016-09-13 Thread Thomas 'PointedEars' Lahn
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?

2016-09-13 Thread Random832
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?

2016-09-13 Thread Sibylle Koczian

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?

2016-09-13 Thread Chris Angelico
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?

2016-09-13 Thread Antoon Pardon
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?

2016-09-13 Thread 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". :)

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?

2016-09-13 Thread Antoon Pardon
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?

2016-09-12 Thread Ned Batchelder
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?

2016-09-12 Thread 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.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to extend a tuple of tuples?

2016-09-12 Thread BartC

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?

2016-09-12 Thread John Gordon
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?

2016-09-09 Thread Lawrence D’Oliveiro
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?

2016-09-09 Thread Rustom Mody
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?

2016-09-09 Thread Chris Angelico
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?

2016-09-09 Thread Frank Millman
"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?

2016-09-09 Thread Ned Batchelder
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?

2016-09-09 Thread Frank Millman
"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?

2016-09-09 Thread Steve D'Aprano
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?

2016-09-09 Thread Jussi Piitulainen
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?

2016-09-09 Thread Ben Finney
"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?

2016-09-09 Thread Rustom Mody
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?

2016-09-09 Thread dieter
"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?

2016-09-08 Thread Frank Millman

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