Accepting multiple mappings as positional arguments to create dicts

Hi! I thought that maybe dict could accept several mappings as positional arguments, like this: class Dict4(dict):
AFAIK, this wouldn't create compatibility problems, since you can't pass two positional arguments now anyways. It would be useful to solve the "sum/union dicts" discussion, for example: requests.get(url, params=dict(params, {'foo': bar}) Whar are your thoughts?

In which way would this be different to {**mapping1, **mapping2, **mapping3} ? On 8 April 2018 at 22:18, Andrés Delfino <adelfino@gmail.com> wrote:
-- Daniel F. Moisset - UK Country Manager - Machinalis Limited www.machinalis.co.uk <http://www.machinalis.com> Skype: @dmoisset T: + 44 7398 827139 1 Fore St, London, EC2Y 9DT Machinalis Limited is a company registered in England and Wales. Registered number: 10574987.

No worries, already implemented features happens so often in this list that there's a story about Guido going back in a time machine to implement them ;-) Just wanted to check that I had understood what you suggested correctly On 9 April 2018 at 12:42, Andrés Delfino <adelfino@gmail.com> wrote:
-- Daniel F. Moisset - UK Country Manager - Machinalis Limited www.machinalis.co.uk <http://www.machinalis.com> Skype: @dmoisset T: + 44 7398 827139 1 Fore St, London, EC2Y 9DT Machinalis Limited is a company registered in England and Wales. Registered number: 10574987.

On Wed, Apr 11, 2018 at 02:22:08PM +1000, Chris Angelico wrote:
It does to me. On the one hand, we have a function call (okay, technically a type...) "dict()" that can be googled on, with three arguments; on the other hand, we have syntax that looks like a set {...} and contains the obscure ** prefix operator which is hard to google for. -- Steve

On Wed, Apr 11, 2018 at 2:44 PM, Steven D'Aprano <steve@pearwood.info> wrote:
True, you can google 'dict'. But the double-star operator is exactly the same as is used in kwargs, and actually, I *can* search for it. https://www.google.com.au/search?q=python+** Lots of results for kwargs, which is a good start. (DuckDuckGo is less useful here, though it too is capable of searching for "**". It just gives more results about exponentiation than about packing/unpacking.) The googleability argument may have been a killer a few years ago, but search engines get smarter every day [1], and it's most definitely possible to search for operators. Or at least some of them; Google and DDG don't give me anything useful for "python @". ChrisA [1] and a search engine can help you find SmarterEveryDay, not that he talks about Python

Ok, we can haggle the finer details and I admit once you learn the syntax it isn't substantially harder. Simply, I've found the dict() a bit easier to mentally parse at a glance. Also, to add I've always expected multiple args to work with it, and am always surprised when it doesn't. Would never have thought of this unpacking syntax if I didn't know that's the way its done now, but often have to think about it for a second or two. On 2018-04-10 22:22, Chris Angelico wrote:
On Wed, Apr 11, 2018 at 2:44 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Apr 11, 2018 at 02:22:08PM +1000, Chris Angelico wrote:

Extending the original idea, IMHO it would make sense for the dict constructor to create a new dictionary not only from several mappings, but mixing mappings and iterables too. Consider this example: x = [(1, 'one')] y = {2: 'two'} Now: {**dict(x), **y} Proposed: dict(x, y) I think this extension makes the call ostensibly easier to read and grep. I believe we are safe regarding compatibility issues, right? What do you guys think? On Wed, Apr 11, 2018 at 4:44 AM, Mike Miller <python-ideas@mgmiller.net> wrote:

While we're on the subject, I've tried to add dicts a few times over the years to get a new one but it doesn't work: d3 = d1 + d2 # TypeError Thinking a bit, set union is probably a better analogue, but it doesn't work either: d3 = d1 | d2 # TypeError Where the last value of any duplicate keys should win. -Mike On 2018-04-12 06:46, Andrés Delfino wrote:

There's a long thread about the subject: https://mail.python.org/pipermail/python-ideas/2015-February/031748.html I suggest to avoid the matter altogether :) On Thu, Apr 12, 2018 at 4:15 PM, Mike Miller <python-ideas@mgmiller.net> wrote:

I usually go with + only to find out that dict was something special here. ;-) Then, I use .update only to find out, that it's in-place and I need to join more than two. Then, I use some sort of dict comprehension or the dict constructor etc. Naively, I would say + is what comes to mind easily. :D Then, even sum(my_dicts) would work. ;-) on-topic: Multiple arguments to dict(*my_dicts) just complements the alternative {**...} comprehension. So, it seems legit. +1 On 12.04.2018 21:32, Andrés Delfino wrote:

09.04.18 00:18, Andrés Delfino пише:
It is easy to make the dict constructor merging several positional arguments. But this is not a tiny harmless change, it will start a cascade of other changes. After changing the dict constructor, we will need to update the dict.update() method too. Constructors and update() methods of dict subclasses (OrderedDict, defaultdict, Counter, and more specialized classes) should be updated too. UserDict, WeakKeyDictionary, WeakValueDictionary are next. After that we will have a pressure of updating constructors and update() methods of abstract classes Mapping and MutableMapping. This change will break a lot of third-party code that implement concrete implementations of these classes, because adding support of new arguments in the method of abstract class breaks an interface. We will be able to pass this path (we have already passed it), but we must realize how long it is.

I think the update method can (and personally, should) stay unchanged: spam.update(dict(x, y)) seems succinct and elegant enough, with the proposed constructor syntax. Sorry my ignorance, do (Mutable)Mapping ABC say anything about constructors? On Thu, Apr 12, 2018 at 12:45 PM, Serhiy Storchaka <storchaka@gmail.com> wrote:

It's a slippery slope indeed. While having to change update() alone wouldn't worry me, the subclass constructors do seem like they are going to want changing too, and that's indeed a bit much. So let's back off a bit. Not every three lines of code need a built-in shorthand. On Thu, Apr 12, 2018 at 8:45 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido)

On 2018-04-12 18:03, Guido van Rossum wrote:
This is disappointing since the dictionary is one of the most used but simultaneously limited of the builtin types. It doesn't support a lot of operations that strings, lists, tuples, sets, etc do. These are the little niceties that make Python fun to program in. But, for some reason we're stingy when it comes to dictionaries, the foundation of the language. Has anyone disagreed the dict constructor shouldn't take multiple arguments? Also, it isn't always three lines of code, but expands with the number that need to be merged. My guess is that the dict is used an order of magnitude more than specialized subclasses, even more so now that the Ordered variant is unnecessary in newer versions. It wouldn't bother me at all if it took a few years for the improvement to get rolled out to subclasses or never, it's quite a minor disappointment compared to getting the functionality ~90% of the time. Also wouldn't mind helping out with the subclasses if there is some lifting that needed to be done. -Mike

In which way would this be different to {**mapping1, **mapping2, **mapping3} ? On 8 April 2018 at 22:18, Andrés Delfino <adelfino@gmail.com> wrote:
-- Daniel F. Moisset - UK Country Manager - Machinalis Limited www.machinalis.co.uk <http://www.machinalis.com> Skype: @dmoisset T: + 44 7398 827139 1 Fore St, London, EC2Y 9DT Machinalis Limited is a company registered in England and Wales. Registered number: 10574987.

No worries, already implemented features happens so often in this list that there's a story about Guido going back in a time machine to implement them ;-) Just wanted to check that I had understood what you suggested correctly On 9 April 2018 at 12:42, Andrés Delfino <adelfino@gmail.com> wrote:
-- Daniel F. Moisset - UK Country Manager - Machinalis Limited www.machinalis.co.uk <http://www.machinalis.com> Skype: @dmoisset T: + 44 7398 827139 1 Fore St, London, EC2Y 9DT Machinalis Limited is a company registered in England and Wales. Registered number: 10574987.

On Wed, Apr 11, 2018 at 02:22:08PM +1000, Chris Angelico wrote:
It does to me. On the one hand, we have a function call (okay, technically a type...) "dict()" that can be googled on, with three arguments; on the other hand, we have syntax that looks like a set {...} and contains the obscure ** prefix operator which is hard to google for. -- Steve

On Wed, Apr 11, 2018 at 2:44 PM, Steven D'Aprano <steve@pearwood.info> wrote:
True, you can google 'dict'. But the double-star operator is exactly the same as is used in kwargs, and actually, I *can* search for it. https://www.google.com.au/search?q=python+** Lots of results for kwargs, which is a good start. (DuckDuckGo is less useful here, though it too is capable of searching for "**". It just gives more results about exponentiation than about packing/unpacking.) The googleability argument may have been a killer a few years ago, but search engines get smarter every day [1], and it's most definitely possible to search for operators. Or at least some of them; Google and DDG don't give me anything useful for "python @". ChrisA [1] and a search engine can help you find SmarterEveryDay, not that he talks about Python

Ok, we can haggle the finer details and I admit once you learn the syntax it isn't substantially harder. Simply, I've found the dict() a bit easier to mentally parse at a glance. Also, to add I've always expected multiple args to work with it, and am always surprised when it doesn't. Would never have thought of this unpacking syntax if I didn't know that's the way its done now, but often have to think about it for a second or two. On 2018-04-10 22:22, Chris Angelico wrote:
On Wed, Apr 11, 2018 at 2:44 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Apr 11, 2018 at 02:22:08PM +1000, Chris Angelico wrote:

Extending the original idea, IMHO it would make sense for the dict constructor to create a new dictionary not only from several mappings, but mixing mappings and iterables too. Consider this example: x = [(1, 'one')] y = {2: 'two'} Now: {**dict(x), **y} Proposed: dict(x, y) I think this extension makes the call ostensibly easier to read and grep. I believe we are safe regarding compatibility issues, right? What do you guys think? On Wed, Apr 11, 2018 at 4:44 AM, Mike Miller <python-ideas@mgmiller.net> wrote:

While we're on the subject, I've tried to add dicts a few times over the years to get a new one but it doesn't work: d3 = d1 + d2 # TypeError Thinking a bit, set union is probably a better analogue, but it doesn't work either: d3 = d1 | d2 # TypeError Where the last value of any duplicate keys should win. -Mike On 2018-04-12 06:46, Andrés Delfino wrote:

There's a long thread about the subject: https://mail.python.org/pipermail/python-ideas/2015-February/031748.html I suggest to avoid the matter altogether :) On Thu, Apr 12, 2018 at 4:15 PM, Mike Miller <python-ideas@mgmiller.net> wrote:

I usually go with + only to find out that dict was something special here. ;-) Then, I use .update only to find out, that it's in-place and I need to join more than two. Then, I use some sort of dict comprehension or the dict constructor etc. Naively, I would say + is what comes to mind easily. :D Then, even sum(my_dicts) would work. ;-) on-topic: Multiple arguments to dict(*my_dicts) just complements the alternative {**...} comprehension. So, it seems legit. +1 On 12.04.2018 21:32, Andrés Delfino wrote:

09.04.18 00:18, Andrés Delfino пише:
It is easy to make the dict constructor merging several positional arguments. But this is not a tiny harmless change, it will start a cascade of other changes. After changing the dict constructor, we will need to update the dict.update() method too. Constructors and update() methods of dict subclasses (OrderedDict, defaultdict, Counter, and more specialized classes) should be updated too. UserDict, WeakKeyDictionary, WeakValueDictionary are next. After that we will have a pressure of updating constructors and update() methods of abstract classes Mapping and MutableMapping. This change will break a lot of third-party code that implement concrete implementations of these classes, because adding support of new arguments in the method of abstract class breaks an interface. We will be able to pass this path (we have already passed it), but we must realize how long it is.

I think the update method can (and personally, should) stay unchanged: spam.update(dict(x, y)) seems succinct and elegant enough, with the proposed constructor syntax. Sorry my ignorance, do (Mutable)Mapping ABC say anything about constructors? On Thu, Apr 12, 2018 at 12:45 PM, Serhiy Storchaka <storchaka@gmail.com> wrote:

It's a slippery slope indeed. While having to change update() alone wouldn't worry me, the subclass constructors do seem like they are going to want changing too, and that's indeed a bit much. So let's back off a bit. Not every three lines of code need a built-in shorthand. On Thu, Apr 12, 2018 at 8:45 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
-- --Guido van Rossum (python.org/~guido)

On 2018-04-12 18:03, Guido van Rossum wrote:
This is disappointing since the dictionary is one of the most used but simultaneously limited of the builtin types. It doesn't support a lot of operations that strings, lists, tuples, sets, etc do. These are the little niceties that make Python fun to program in. But, for some reason we're stingy when it comes to dictionaries, the foundation of the language. Has anyone disagreed the dict constructor shouldn't take multiple arguments? Also, it isn't always three lines of code, but expands with the number that need to be merged. My guess is that the dict is used an order of magnitude more than specialized subclasses, even more so now that the Ordered variant is unnecessary in newer versions. It wouldn't bother me at all if it took a few years for the improvement to get rolled out to subclasses or never, it's quite a minor disappointment compared to getting the functionality ~90% of the time. Also wouldn't mind helping out with the subclasses if there is some lifting that needed to be done. -Mike
participants (9)
-
Andrés Delfino
-
Chris Angelico
-
Daniel Moisset
-
Ed Kellett
-
Guido van Rossum
-
Mike Miller
-
Serhiy Storchaka
-
Steven D'Aprano
-
Sven R. Kunze