[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