Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #99091 > unrolled thread
| Started by | Laura Creighton <lac@openend.se> |
|---|---|
| First post | 2015-11-19 21:18 +0100 |
| Last post | 2015-11-25 10:13 +0100 |
| Articles | 20 on this page of 86 — 17 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Laura Creighton <lac@openend.se> - 2015-11-19 21:18 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-19 22:57 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Laura Creighton <lac@openend.se> - 2015-11-19 23:41 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-20 14:00 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-20 11:33 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-25 09:14 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-25 21:52 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-25 13:25 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 13:20 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ned Batchelder <ned@nedbatchelder.com> - 2015-11-25 07:13 -0800
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Laura Creighton <lac@openend.se> - 2015-11-25 16:59 +0100
Multiplication [was Re: Late-binding of function defaults] Steven D'Aprano <steve@pearwood.info> - 2015-11-26 05:09 +1100
Re: Multiplication [was Re: Late-binding of function defaults] Laura Creighton <lac@openend.se> - 2015-11-25 19:45 +0100
Re: Multiplication [was Re: Late-binding of function defaults] Marko Rauhamaa <marko@pacujo.net> - 2015-11-25 23:04 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Arie van Wingerden <xapwing@gmail.com> - 2015-11-25 17:12 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 03:29 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 17:18 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ian Kelly <ian.g.kelly@gmail.com> - 2015-11-25 11:03 -0700
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 18:48 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-11-25 20:50 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 21:56 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 00:16 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 22:41 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-26 11:31 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-26 01:23 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ned Batchelder <ned@nedbatchelder.com> - 2015-11-25 17:52 -0800
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ben Finney <ben+python@benfinney.id.au> - 2015-11-26 16:08 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-11-26 06:39 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-26 09:31 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-26 12:53 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-27 00:15 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-26 14:40 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) MRAB <python@mrabarnett.plus.com> - 2015-11-26 16:14 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-26 22:27 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-27 10:07 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Random832 <random832@fastmail.com> - 2015-11-26 19:15 -0500
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-27 11:48 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) MRAB <python@mrabarnett.plus.com> - 2015-11-27 01:15 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) MRAB <python@mrabarnett.plus.com> - 2015-11-26 16:16 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-11-27 10:48 +1300
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-27 12:46 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-27 02:01 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 08:41 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-27 12:09 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-27 10:31 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-27 13:30 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ben Finney <ben+python@benfinney.id.au> - 2015-11-26 06:57 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-25 23:00 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Emile van Sebille <emile@fenx.com> - 2015-11-25 10:56 -0800
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-26 13:01 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 00:24 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-25 15:17 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Emile van Sebille <emile@fenx.com> - 2015-11-25 10:51 -0800
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-25 19:32 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-25 10:43 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-25 21:58 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 12:35 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-25 15:06 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 13:37 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-25 15:53 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) BartC <bc@freeuk.com> - 2015-11-25 14:34 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-11-25 13:32 -0500
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-26 11:53 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 08:52 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 18:14 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 10:27 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 19:34 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 12:54 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 22:04 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 13:23 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 22:35 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 14:03 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-27 12:43 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-26 09:45 +0100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-11-27 10:20 +1300
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Marko Rauhamaa <marko@pacujo.net> - 2015-11-26 23:36 +0200
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Steven D'Aprano <steve@pearwood.info> - 2015-11-27 12:23 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-11-26 11:17 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 00:44 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ben Finney <ben+python@benfinney.id.au> - 2015-11-26 06:55 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Random832 <random832@fastmail.com> - 2015-11-26 00:52 +0000
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Ian Kelly <ian.g.kelly@gmail.com> - 2015-11-25 20:01 -0700
Semantics of collection types (was: Late-binding of function defaults (was Re: What is a function parameter =[] for?)) Ben Finney <ben+python@benfinney.id.au> - 2015-11-26 16:04 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Chris Angelico <rosuav@gmail.com> - 2015-11-26 00:35 +1100
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Larry Hudson <orgnut@yahoo.com> - 2015-11-25 22:44 -0800
Re: Late-binding of function defaults (was Re: What is a function parameter =[] for?) Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2015-11-25 10:13 +0100
Page 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2015-11-25 14:34 +0000 |
| Message-ID | <n34gor$kq8$1@dont-email.me> |
| In reply to | #99453 |
On 25/11/2015 13:53, Marko Rauhamaa wrote: > BartC <bc@freeuk.com>: > >> Using tuples in the same way that other languages implement records is >> going to be difficult if you can't change the values of the fields! > > Guido could decide tomorrow that tuples are mutable. (Could that be done without breaking existing code? And what then would be the difference between them and lists?) > Anyway, Python has two ways to represent records: classes and tuples. > Tuples are nice because they are concise and ad hoc. Often you start > with a scalar value, then turn it into a tuple. After a while your handy > tuple turns out a bit cumbersome to use so you convert it into an actual > class. This is how records are handled in another language which I believe is simpler than Python: http://pastebin.com/vhsJML8U This also implements my example from earlier in the thread. Now compare with Python's approach. OK, that also needs two concepts, a list, and a record. But the distinction is now completely obvious. Records are also mutable. It would also be clear why you can't append to a record. Now try explaining again to me how you would use tuples for the same thing... -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2015-11-25 13:32 -0500 |
| Message-ID | <mailman.86.1448476375.20593.python-list@python.org> |
| In reply to | #99457 |
On Wed, 25 Nov 2015 14:34:12 +0000, BartC <bc@freeuk.com> declaimed the
following:
>On 25/11/2015 13:53, Marko Rauhamaa wrote:
>Now try explaining again to me how you would use tuples for the same
>thing...
You wouldn't -- you would decompose the tuple and create a new one from
the parts, with changes as needed.
And as hinted, tuples were immutable in Python so they could be used as
keys in dictionaries. The associated concept then also makes sense --
lists commonly holding multiple independent entities of the same type vs an
ordered collection of dependent entities of different types.
And tuple, as used by Python, is a close match to tuple as used by
relational theory -- everything in the tuple is related in some way. If one
is to make a change to a component of a relational tuple, it is no longer
the same tuple.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-26 11:53 +1100 |
| Message-ID | <56565822$0$1617$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #99457 |
On Thu, 26 Nov 2015 01:34 am, BartC wrote:
> On 25/11/2015 13:53, Marko Rauhamaa wrote:
>> BartC <bc@freeuk.com>:
>>
>>> Using tuples in the same way that other languages implement records is
>>> going to be difficult if you can't change the values of the fields!
>>
>> Guido could decide tomorrow that tuples are mutable.
>
> (Could that be done without breaking existing code? And what then would
> be the difference between them and lists?)
No it could not, and no Guido could not decide to make them mutable.
Well, strictly speaking he could make that decision, but the other core
developers would not go along with such a stupid backwards-incompatible
change. I don't know what would happen if Guido did make that decision -- I
suppose it would provoke some sort of constitutional crisis (figuratively
speaking), like what would happen if the Queen of the UK refused to sign
into law legislation after being lawfully asked to do so by the Prime
Minister. (The Queen has the power to reject any legislation put to her by
the Prime Minister, so long as she does not actually make use of that
power.)
Guido, as BDFL, has every right to make tuples mutable, or remove numbers
from the language, so long as he does not actually do so.
Making tuples mutable would break their use as dictionary keys, which is a
*critical* use.
https://docs.python.org/2/faq/design.html#why-must-dictionary-keys-be-immutable
>> Anyway, Python has two ways to represent records: classes and tuples.
>> Tuples are nice because they are concise and ad hoc. Often you start
>> with a scalar value, then turn it into a tuple. After a while your handy
>> tuple turns out a bit cumbersome to use so you convert it into an actual
>> class.
>
> This is how records are handled in another language which I believe is
> simpler than Python: http://pastebin.com/vhsJML8U
>
> This also implements my example from earlier in the thread. Now compare
> with Python's approach.
>
> OK, that also needs two concepts, a list, and a record. But the
> distinction is now completely obvious. Records are also mutable. It
> would also be clear why you can't append to a record.
>
> Now try explaining again to me how you would use tuples for the same
> thing...
In Pascal, strings are mutable. (Well, technically, standard Pascal doesn't
define a string data type, but most implementations do.) So you typically
have some function like:
insert(thestring, substring, pos)
which modifies thestring in place. In Python, strings are immutable, so the
equivalent of insert() would be a function that returns a new string:
thestring = insert(thestring, substring, pos)
It's not exactly an earth-shattering difference.
The implementation is simple that it is almost pointless to put it in a
function:
def insert(s, substring, pos):
return s[:pos] + substring + s[pos:]
Tuples-as-records are no different. Instead of modifying the existing
record, you create a new one. If that's inconvenient, then use a class,
which will be mutable by default.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 08:52 +0200 |
| Message-ID | <87oaeh2qy0.fsf@elektro.pacujo.net> |
| In reply to | #99515 |
Steven D'Aprano <steve@pearwood.info>:
> Making tuples mutable would break their use as dictionary keys, which is a
> *critical* use.
No, it wouldn't. Any object that provides __hash__() and __eq__() can be
used as a key.
Nothing prevents using mutable objects as keys in Python.
Egon Spengler: There's something very important I forgot to tell you.
Peter Venkman: What?
Spengler: Don't use mutable keys.
Venkman: Why?
Spengler: It would be bad.
Venkman: I'm fuzzy on the whole good/bad thing. What do you mean,
"bad"?
Spengler: Try to imagine all life as you know it stopping
instantaneously and every molecule in your body exploding at the
speed of light.
Ray Stantz: Total protonic reversal!
Venkman: Right. That's bad. Okay. All right. Important safety tip.
Thanks, Egon.
Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-26 18:14 +1100 |
| Message-ID | <mailman.117.1448525450.20593.python-list@python.org> |
| In reply to | #99532 |
On Thu, Nov 26, 2015 at 5:52 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Steven D'Aprano <steve@pearwood.info>: > >> Making tuples mutable would break their use as dictionary keys, which is a >> *critical* use. > > No, it wouldn't. Any object that provides __hash__() and __eq__() can be > used as a key. > > Nothing prevents using mutable objects as keys in Python. > > Sure, you _can_. But if the key's hash changes between dict insertion and retrieval, all manner of invariants will break, and likewise if two equal objects have different hashes. From which you can deduce logically that any object used as a key must remain (not) equal to everything that it was (not) equal to from that time until it is looked up... which basically means its value mustn't change. It must be immutable. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 10:27 +0200 |
| Message-ID | <87a8q1f9ni.fsf@elektro.pacujo.net> |
| In reply to | #99536 |
Chris Angelico <rosuav@gmail.com>: > On Thu, Nov 26, 2015 at 5:52 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >> Nothing prevents using mutable objects as keys in Python. > > Sure, you _can_. But if the key's hash changes between dict insertion > and retrieval, all manner of invariants will break, and likewise if > two equal objects have different hashes. From which you can deduce > logically that any object used as a key must remain (not) equal to > everything that it was (not) equal to from that time until it is > looked up... which basically means its value mustn't change. It must > be immutable. What I'm saying is that Python does not prevent mutable keys but tries to do that with lists and tuples. I think Python should stop trying. I have wanted to use lists as keys, and there should be no reason to allow mutable tuples. It should be enough to say that the behavior of a dictionary is undefined if a key should mutate on the fly. Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-26 19:34 +1100 |
| Message-ID | <mailman.120.1448526890.20593.python-list@python.org> |
| In reply to | #99538 |
On Thu, Nov 26, 2015 at 7:27 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Chris Angelico <rosuav@gmail.com>: > >> On Thu, Nov 26, 2015 at 5:52 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >>> Nothing prevents using mutable objects as keys in Python. >> >> Sure, you _can_. But if the key's hash changes between dict insertion >> and retrieval, all manner of invariants will break, and likewise if >> two equal objects have different hashes. From which you can deduce >> logically that any object used as a key must remain (not) equal to >> everything that it was (not) equal to from that time until it is >> looked up... which basically means its value mustn't change. It must >> be immutable. > > What I'm saying is that Python does not prevent mutable keys but tries > to do that with lists and tuples. > > I think Python should stop trying. > > I have wanted to use lists as keys, and there should be no reason to > allow mutable tuples. It should be enough to say that the behavior of a > dictionary is undefined if a key should mutate on the fly. Python defines dict-key-validity as being synonymous with hashability. It's up to the class author to make sure the object's hash is useful. Behaviour being undefined works just fine [1] in C. It's not so popular in Python. I don't think we want to have myriad new and experienced programmers trying to figure out why square brackets in dict keys are usually fine but occasionally not. ChrisA [1] For some definition of "fine", anyway.
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 12:54 +0200 |
| Message-ID | <87610pf2uq.fsf@elektro.pacujo.net> |
| In reply to | #99541 |
Chris Angelico <rosuav@gmail.com>:
> On Thu, Nov 26, 2015 at 7:27 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> I have wanted to use lists as keys, and there should be no reason to
>> allow mutable tuples. It should be enough to say that the behavior of
>> a dictionary is undefined if a key should mutate on the fly.
>
> Python defines dict-key-validity as being synonymous with hashability.
> It's up to the class author to make sure the object's hash is useful.
>>> hash([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Annoying.
> Behaviour being undefined works just fine [1] in C. It's not so
> popular in Python. I don't think we want to have myriad new and
> experienced programmers trying to figure out why square brackets in
> dict keys are usually fine but occasionally not.
But there's no way to enforce that with any of the myriad new classes.
Ye blind guides, which strain at a gnat, and swallow a camel.
But I say unto you, Swallow the gnat as well.
Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-26 22:04 +1100 |
| Message-ID | <mailman.127.1448535849.20593.python-list@python.org> |
| In reply to | #99550 |
On Thu, Nov 26, 2015 at 9:54 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Chris Angelico <rosuav@gmail.com>: > >> On Thu, Nov 26, 2015 at 7:27 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >>> I have wanted to use lists as keys, and there should be no reason to >>> allow mutable tuples. It should be enough to say that the behavior of >>> a dictionary is undefined if a key should mutate on the fly. >> >> Python defines dict-key-validity as being synonymous with hashability. >> It's up to the class author to make sure the object's hash is useful. > > >>> hash([]) > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: unhashable type: 'list' > > Annoying. Yes, it's really annoying that you get an immediate exception instead of unpredictably getting bizarre failures that depend on the exact bucket sizes and dict size and so on. It's such a pain to get told exactly where the problem is. >> Behaviour being undefined works just fine [1] in C. It's not so >> popular in Python. I don't think we want to have myriad new and >> experienced programmers trying to figure out why square brackets in >> dict keys are usually fine but occasionally not. > > But there's no way to enforce that with any of the myriad new classes. Python tends to assume that programmers are intelligent people who are prepared to fix their mistakes. As a general rule, if you define __eq__, you should probably define __hash__ as well, and then you need to know what you're doing; specifically, the invariant that if a==b, hash(a)==hash(b). Python doesn't enforce that because it's impossible to enforce. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 13:23 +0200 |
| Message-ID | <87wpt5dmxg.fsf@elektro.pacujo.net> |
| In reply to | #99552 |
Chris Angelico <rosuav@gmail.com>: > On Thu, Nov 26, 2015 at 9:54 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >> >> >>> hash([]) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> TypeError: unhashable type: 'list' >> >> Annoying. > > Yes, it's really annoying that you get an immediate exception instead > of unpredictably getting bizarre failures that depend on the exact > bucket sizes and dict size and so on. It's such a pain to get told > exactly where the problem is. The problem is that lists don't have __hash__ and __eq__ defined. > Python tends to assume that programmers are intelligent people who are > prepared to fix their mistakes. It's not letting me in the case of list. Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-26 22:35 +1100 |
| Message-ID | <mailman.131.1448537758.20593.python-list@python.org> |
| In reply to | #99557 |
On Thu, Nov 26, 2015 at 10:23 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Chris Angelico <rosuav@gmail.com>: > >> On Thu, Nov 26, 2015 at 9:54 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >>> >>> >>> hash([]) >>> Traceback (most recent call last): >>> File "<stdin>", line 1, in <module> >>> TypeError: unhashable type: 'list' >>> >>> Annoying. >> >> Yes, it's really annoying that you get an immediate exception instead >> of unpredictably getting bizarre failures that depend on the exact >> bucket sizes and dict size and so on. It's such a pain to get told >> exactly where the problem is. > > The problem is that lists don't have __hash__ and __eq__ defined. They do define equality. And it depends on their contents, ergo there cannot be a stable hash. This is NOT a problem. This is the concept of unhashability behaving EXACTLY CORRECTLY. Sorry to shout, but this is another case of refusing to accept what has been explained as having good reason, and I'm getting a little tired of it. >> Python tends to assume that programmers are intelligent people who are >> prepared to fix their mistakes. > > It's not letting me in the case of list. Actually it is. Your mistake is trying to use a list as a dict key. You have a solution available: use a tuple. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 14:03 +0200 |
| Message-ID | <87oaehdl24.fsf@elektro.pacujo.net> |
| In reply to | #99561 |
Chris Angelico <rosuav@gmail.com>: > On Thu, Nov 26, 2015 at 10:23 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >> It's not letting me in the case of list. > > Actually it is. Your mistake is trying to use a list as a dict key. > You have a solution available: use a tuple. Yes, or wrap the list in a class. Marko
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-27 12:43 +1100 |
| Message-ID | <5657b52c$0$1617$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #99557 |
On Thu, 26 Nov 2015 10:23 pm, Marko Rauhamaa wrote:
> Chris Angelico <rosuav@gmail.com>:
>
>> On Thu, Nov 26, 2015 at 9:54 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
>>>
>>> >>> hash([])
>>> Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> TypeError: unhashable type: 'list'
>>>
>>> Annoying.
>>
>> Yes, it's really annoying that you get an immediate exception instead
>> of unpredictably getting bizarre failures that depend on the exact
>> bucket sizes and dict size and so on. It's such a pain to get told
>> exactly where the problem is.
>
> The problem is that lists don't have __hash__ and __eq__ defined.
I'm pretty sure that lists have __eq__ defined :-P
>> Python tends to assume that programmers are intelligent people who are
>> prepared to fix their mistakes.
>
> It's not letting me in the case of list.
Less whining, more programming:
class MyList(list):
def __hash__(self):
return 1
There you go, problem solved. New problems are your responsibility:
py> a = MyList([1, 2])
py> d = {a: "spam"}
py> d[MyList([1, 2])] # Looks good so far.
'spam'
py> a.append(3)
py> d[MyList([1, 2])] # Where did my key go?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: [1, 2]
py> b = MyList([1, 3])
py> d[b] = "eggs"
py> d[MyList([1, 3])] # So far so good.
'eggs'
py> b[1] -= 1
py> b.append(3)
py> d[b] # What?
'spam'
All I can say is, this would be an absolutely awesome feature for Python to
have, if you were being paid by the hour for debugging.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2015-11-26 09:45 +0100 |
| Message-ID | <mailman.124.1448527548.20593.python-list@python.org> |
| In reply to | #99538 |
Op 26-11-15 om 09:27 schreef Marko Rauhamaa: > Chris Angelico <rosuav@gmail.com>: > >> On Thu, Nov 26, 2015 at 5:52 PM, Marko Rauhamaa <marko@pacujo.net> wrote: >>> Nothing prevents using mutable objects as keys in Python. >> Sure, you _can_. But if the key's hash changes between dict insertion >> and retrieval, all manner of invariants will break, and likewise if >> two equal objects have different hashes. From which you can deduce >> logically that any object used as a key must remain (not) equal to >> everything that it was (not) equal to from that time until it is >> looked up... which basically means its value mustn't change. It must >> be immutable. > What I'm saying is that Python does not prevent mutable keys but tries > to do that with lists and tuples. > > I think Python should stop trying. > > I have wanted to use lists as keys, and there should be no reason to > allow mutable tuples. It should be enough to say that the behavior of a > dictionary is undefined if a key should mutate on the fly. Maybe python could introduce a dictionary that copies the keys in and out the dictionary. In that case keys can be mutable without that being a problem for the dictionary, because the dictionary works with it's own copy of the key that it doesn't mutate. -- Antoon.
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-11-27 10:20 +1300 |
| Message-ID | <dbpbdrFce6nU1@mid.individual.net> |
| In reply to | #99538 |
Marko Rauhamaa wrote: > What I'm saying is that Python does not prevent mutable keys but tries > to do that with lists and tuples. > > I think Python should stop trying. Do you volunteer to answer all the posts from beginners complaining that "the dict type is broken" because they used a list as a key and then mutated it? -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-11-26 23:36 +0200 |
| Message-ID | <87egfc30ky.fsf@elektro.pacujo.net> |
| In reply to | #99599 |
Gregory Ewing <greg.ewing@canterbury.ac.nz>: > Marko Rauhamaa wrote: >> What I'm saying is that Python does not prevent mutable keys but >> tries to do that with lists and tuples. >> >> I think Python should stop trying. > > Do you volunteer to answer all the posts from beginners complaining > that "the dict type is broken" because they used a list as a key and > then mutated it? What happened to consenting adults? Even Java (of all languages) allows lists to be keys and simply notes: Note: great care must be exercised if mutable objects are used as map keys. <URL: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html> Marko
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-11-27 12:23 +1100 |
| Message-ID | <5657b081$0$1586$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #99538 |
On Thu, 26 Nov 2015 07:27 pm, Marko Rauhamaa wrote:
> What I'm saying is that Python does not prevent mutable keys but tries
> to do that with lists and tuples.
>
> I think Python should stop trying.
>
> I have wanted to use lists as keys, and there should be no reason to
> allow mutable tuples. It should be enough to say that the behavior of a
> dictionary is undefined if a key should mutate on the fly.
Well, when you design your own language, you can make all the bad design
decisions you like :-)
Seriously, if you think *this* thread about mutable function defaults has
been long, can you imagine the bug reports and arguments if this was
possible in Python?
L = [1, 2]
d = {L: "found it"}
# much later, after L has been modified...
d[ [1, 2] ]
=> raises KeyError
But even worse:
a = [1, 2]
b = [1, 3]
d = {a: "spam", b: "ham"}
a[1] += 1
What will d[ [1, 3] ] return?
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-11-26 11:17 +0000 |
| Message-ID | <mailman.128.1448536715.20593.python-list@python.org> |
| In reply to | #99532 |
On 26/11/2015 06:52, Marko Rauhamaa wrote: > Steven D'Aprano <steve@pearwood.info>: > >> Making tuples mutable would break their use as dictionary keys, which is a >> *critical* use. > > No, it wouldn't. Any object that provides __hash__() and __eq__() can be > used as a key. > Almost, see https://wiki.python.org/moin/DictionaryKeys. Under the title "Types Usable as Dictionary Keys" it states "The discussion above should explain why Python requires that: To be used as a dictionary key, an object must support the hash function (e.g. through __hash__), equality comparison (e.g. through __eq__ or __cmp__), and must satisfy the correctness condition above." The correctness condition is:- "For such a lookup algorithm to work correctly, the hash functions provided must guarantee that if two keys produce different hash values then the two key objects are not equivalent, that is, for all i1, i2, if hash(i1) != hash(i2), then i1 != i2" Aren't search engines just wonderful :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-11-26 00:44 +1100 |
| Message-ID | <mailman.71.1448459080.20593.python-list@python.org> |
| In reply to | #99445 |
On Thu, Nov 26, 2015 at 12:06 AM, Marko Rauhamaa <marko@pacujo.net> wrote: > However, tuples are a way to represent records, groupings of related > values, where the semantics of each value is determined by its position > in the tuple. The members in a tuple are typically of different data > types. > > Lists are collections of values. Typically, each member of list is of > the same type. This is a distinction I generally make. Putting it another way: a list has the same meaning regardless of how many items are on it (for instance, a shopping list is still a shopping list whether it has five or fifty items on it), where a tuple is a package where each element has a specific meaning (such as Cartesian coordinates; the difference between the position (2,3) and the position (2,3,4) is not just that there's "more position" in the second one - it's a drastically different beast, living in three dimensions instead of two). Nothing in the language enforces this, but the mutability of lists does tend to align well with things that can grow and shrink, and the immutability of tuples makes them more like strings or complex numbers (in fact, a complex number is basically a tuple of two floats). ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-11-26 06:55 +1100 |
| Message-ID | <mailman.90.1448481340.20593.python-list@python.org> |
| In reply to | #99445 |
Chris Angelico <rosuav@gmail.com> writes: > This is a distinction I generally make. Putting it another way: a list > has the same meaning regardless of how many items are on it (for > instance, a shopping list is still a shopping list whether it has five > or fifty items on it), where a tuple is a package where each element > has a specific meaning […] Yes. The disctinction is even clearer, I find, by saying that the *meaning of the position* in the sequence is significant for a tuple, not significant for a list. That is, the ‘2’ in ‘cartesian_point = (2, 3)’ means something different than in ‘cartesian_point = (3, 2)’. Whereas the ‘2’ in ‘test_scores = [2, 3]’ means exactly the same as in ‘test_scores = [3, 2]’. If each position in the sequence gives the value there a different menaning, use a tuple; if not, use a list. > Nothing in the language enforces this, but the mutability of lists > does tend to align well with things that can grow and shrink, and the > immutability of tuples makes them more like strings or complex numbers > (in fact, a complex number is basically a tuple of two floats). Not only the growing and shrinking, but the re-ordering of items in a list should not change the meaning of its items. If you can ‘sort’ the sequence and the items still mean exactly what they did before, then a tuple is the wrong type to use, semantically. -- \ “Crime is contagious… if the government becomes a lawbreaker, | `\ it breeds contempt for the law.” —Justice Louis Brandeis | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
Page 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
Back to top | Article view | comp.lang.python
csiph-web