[Python-ideas] dict '+' operator and slicing support for pop
Andrii V. Mishkovskyi
mishok13 at gmail.com
Tue Mar 17 16:00:52 CET 2009
First of all, this is my first attempt at submitting an idea to
python-ideas. So, here it goes. :)
1. Add ability to use '+' operator for dicts
I often wonder why list and tuple instances have '+' and '+='
operators but dicts don't?
It's not that rare in my code (and code written by others, as it
seems) that i have to write:
a.update(b)
return a
I do understand that adding additional magic method may be
inappropriate for dict, but I think it would be nice addition to a
language. So, my proposal is that:
x = a + b
would become equivalent to
x = dict(a, **b)
a += b
would become equivalent to
a.update(b)
And the example I gave before would be translated to:
return a + b
Note, that there is a difference between these two examples in
semantics, the latter one creates a new dict. But that's what user
doesn't care about in 99% of use-cases.
A very basic implementation in Python:
>>> class Dict(dict):
... def __add__(self, other):
... return self.__class__(self, **other)
... def __iadd__(self, other):
... self.update(other)
... return self
...
>>> a = Dict(foo=12, bar=14, baz=16)
>>> b = Dict(spam=13, eggs=17, bacon=19)
>>> a + b
{'bar': 14, 'spam': 13, 'bacon': 19, 'eggs': 17, 'foo': 12, 'baz': 16}
>>> a += b
>>> a
{'bar': 14, 'spam': 13, 'bacon': 19, 'eggs': 17, 'foo': 12, 'baz': 16}
>>> b
{'eggs': 17, 'bacon': 19, 'spam': 13}
>>> class Dict(dict):
... def __add__(self, other):
... return self.__class__(self, **other)
... def __iadd__(self, other):
... self.update(other)
... return self
...
>>> a = Dict(foo=12, bar=14, baz=16)
>>> b = Dict(spam=13, eggs=17, bacon=19)
>>> a + b
{'bar': 14, 'spam': 13, 'bacon': 19, 'eggs': 17, 'foo': 12, 'baz': 16}
>>> a += b
>>> a
{'bar': 14, 'spam': 13, 'bacon': 19, 'eggs': 17, 'foo': 12, 'baz': 16}
>>> b
{'eggs': 17, 'bacon': 19, 'spam': 13}
Note: if this is ever going to be implemented, then Mapping ABCs will
have to implement these methods, which doesn't sound like
backwards-compatible to me. :)
2. Ability to use slices in pop
This was discussed earlier (4.5 years ago, actually) in this thread:
http://mail.python.org/pipermail/python-dev/2004-November/049895.html
Even though original request became a full-blown proposal (PEP-3132)
and was implemented in py3k, the internal discussion about pop
allowing slice as arguments has silenced.
There was some positive feedback from Python developers and I think I
can provide a patch for this functionality in 2 weeks. Is there still
some interest in this? There is nothing really hard, this would be
something like this:
>>> class List(list):
... def pop(self, index_or_slice):
... ret = self[index_or_slice]
... del self[index_or_slice]
... return ret
...
>>> x = List(range(10))
>>> x.pop(slice(1, 4))
[1, 2, 3]
>>> x
[0, 4, 5, 6, 7, 8, 9]
>>> x.pop(5)
8
>>> x
[0, 4, 5, 6, 7, 9]
Note: some people think that pop returning different list or item
depending on what is being passed to pop() is bad or something. I
don't see a problem here, because simple some_list[index_or_slice] can
also return list or just one item depending on what type
`index_or_slice` is.
--
Wbr, Andrii V. Mishkovskyi.
He's got a heart of a little child, and he keeps it in a jar on his desk.
More information about the Python-ideas
mailing list