[Python-Dev] PySequence_Concat for dicts

Guido van Rossum guido at python.org
Sat Jan 12 04:22:19 CET 2008


On Jan 11, 2008 5:21 PM, Raymond Hettinger <python at rcn.com> wrote:
> > I wasn't suggesting that the result of concatenation would
> > be a  chained table, rather that it would perform the
> > equivalent of an  update and return the new dict
> >(the same way extend works for lists)
>
> When does it come-up that you want a third summed dict
> while keeping the two originals around unchanged?  Does
> it matter that the addition is non-commutative?  Would
> a + b + c produce an intermediate a/b combo and then
> another new object for a/b/c so that the entries in
> a get copied twice and memory usage has to hold a, b,
> a/b, c, and a/b/c in memory all at the same time?
> What are the use cases?
>
> FWIW, the Py3.0 API for dicts will support some set-like
> operations.  Perhaps, that fits the bill.

While that was at one point proposed, It's been retracted.

It does suggest that we have two choices for the proposed operation:
d1+d2 or d1|d2. I think the latter may be more appropriate:
len(seq1+seq2) == len(seq1) ++len(seq2), but no such invariant exists
for set union.

I'd like to take an "all or nothing" approach to this: either we
implement the same 4 operations as for sets (|, &, ^ and -) or we
implement none of them. We can assign semantics to these such that if
the values are all the same, these work the same as set operations on
the keys. E.g.:

  {1:1, 2:2} | {2:2, 3:3} == {1:1, 2:2, 3:3}
  {1:1, 2:2} & {2:2, 3:3} == {2:2}
  {1:1, 2:2} ^ {2:2, 3:3} == {1:1, 3:3}
  {1:1, 2:2} - {2:2, 3:3} == {1:1}

If the values differ, we have to decide what happens. For ^ and -, we
only need to take the keys into account. For | I propose that the RHS
wins, matching dict.update(); this makes sense since set.update() is
equivalent to |= for sets, so |= should match dict.update() for dict,
and then | follows. For & I'm on the fence, but I think it's easier to
say that the RHS wins in all cases. So we get:

  {1:1, 2:2} | {2:0, 3:0} = {1:1, 2:0, 3:0}
  {1:1, 2:2} & {2:0, 3:0} = {2:0}
  {1:1, 2:2} ^ {2:0, 3:0} = {1:1, 3:0}
  {1:1, 2:2} - {2:0, 3:0} = {1:1}

(The |=, &=, ^= and -= operators don't pose new problems, they update
the LHS in place.)

I'm not sure where I stand on this proposal -- I guess a +0, if
someone else does the work. (The abc.py module needs to be updated
too.)

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list