[Python-Dev] PySequence_Concat for dicts (original) (raw)

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