On 07/28/2014 10:34 PM, Steven D'Aprano wrote:
On Mon, Jul 28, 2014 at 12:17:10PM -0500, Ron Adam wrote:
On 07/28/2014 11:04 AM, Steven D'Aprano wrote:
[...]
new_dict = a + b + c + d
Pros: + is short to type; subclasses can control the type of new_dict. Cons: dict addition isn't obvious.
I think it's more obvious. It only needs __add__ and __iadd__ methods to make it consistent with the list type. What I meant was that it wasn't obvious what dict1 + dict2 should do, not whether or not the __add__ method exists.
What else could it do besides return a new copy of dict1 updated with dict2 contents? It's an unordered container, so it wouldn't append, and the duplicate keys would be resolved based on the order of evaluation. I don't see any problem with that. I also don't know of any other obvious way to combine two dictionaries. The argument against it, may simply be that it's a feature by design, to have dictionaries unique enough so that code which handles them is clearly specific to them. I'm not sure how strong that logic is though.
I think this added consistency between lists and dicts would be useful. Lists and dicts aren't the same kind of object. I'm not sure it is helpful to force them to be consistent. Should list grow an update() method to make it consistent with dicts? How about setdefault()?
Well, here is how they currently compare.
set(dir(dict)).intersection(set(dir(list))) {'copy', '__hash__', '__format__', '__sizeof__', '__ge__', '__delitem__', '__getitem__', '__dir__', 'pop', '__gt__', '__repr__', '__init__', '__subclasshook__', '__eq__', 'clear', '__len__', '__str__', '__le__', '__new__', '__reduce_ex__', '__doc__', '__getattribute__', '__ne__', '__reduce__', '__contains__', '__delattr__', '__class__', '__lt__', '__setattr__', '__setitem__', '__iter__'}
set(dir(dict)).difference(set(dir(list))) {'popitem', 'update', 'setdefault', 'items', 'values', 'fromkeys', 'get', 'keys'}
set(dir(list)).difference(set(dir(dict))) {'sort', '__mul__', 'remove', '__iadd__', '__reversed__', 'insert', 'extend', 'append', 'count', '__add__', '__rmul__', 'index', '__imul__', 'reverse'}
They do have quite a lot in common already. The usefulness of different types having the same methods is that external code can be less specific to the objects they handle. Of course, if those like methods act too differently they can be surprising as well. That may be the case if '+' and '+=' are used to update dictionaries, but then again, maybe not. (?)
As for being useful, useful for what? Useful how often? I'm sure that one could take any piece of code, no matter how obscure, and say it is useful*somewhere* :-) but the question is whether it is useful enough to be part of the language.
That's where examples will have an advantage over an initial personal opinion. Not that initial opinions aren't useful at first to express support or non-support. I could have just used +1. ;-) Cheers, Ron