[Tutor] Combining dictionaries

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Wed Sep 7 02:31:51 CEST 2005



> >> He wants c = a + b to work when a and b are dictionaries.
> >>
> >> Why is Python broken in such an obvious way?
>
> > It might not be obvious.  If a and b overlap so that they share keys,
> > then we might have the following situation:
>
> I did consider that, but of course, "update" has to deal with that issue
> already.


Hi Mike,

Yes.  The name "update" is provokative enough, though, that it implies
something is being mutated, so there's no expectation of symmetry.



> Then use an operator like "++" which would be non-commutative
> "addition".
>
> >>> a={1:1,2:2}
> >>> b={2:22,3:3}
> >>> c=dict(a)
> >>> c.update(b)         # This would be c = a ++ b
> >>> c
> {1: 1, 2: 22, 3: 3}
>
> >>> c=dict(b)
> >>> c.update(a)         # This would be c = b ++ a
> >>> c
> {1: 1, 2: 2, 3: 3}


Let's make a function out of this:

######
def merge_dictionaries(a, b):
    """Returns a new dictionary whose key/value pairs will either come
    from dictionary a or b.  The mappings in 'a' take precedence over
    those in 'b'."""
    c = dict(b)
    c.update(a)
    return c
######

Would this be sufficient?



> >>> "foo"   "bar "*3
> 'foobar foobar foobar '
>
> >>> "foo" + "bar "*3
> 'foobar bar bar '
>
> This also seems like a nasty bug (to me, at least).  Because one would
> think that the "*" operator would bind more closely than the '"' or
> implied concatenation would.

I see what you're trying to do, but it won't work:  implicit literal
string concatenation only works between literal strings, that is, strings
that we enter with quotes.

Don't use it: it's easy to misunderstand what it's doing.  What you're
seeing above is not technically a bug: it's working as designed.  What you
mean to say is that it's unexpected to you, and that's true: I don't like
it either.  *grin*

But this one probably won't be cleaned up anytime soon:  too many programs
depend on it behaving this way now.  I do hope that the mythical Python
3000 gets rid of the feature, though, because almost every time I see
implicit literal string concatention on tutor, the user is mistaking what
it is doing.


If you want to report bugs and help improve Python, see:

    http://python.org/dev/

which has links to things like the bug tracker and the community process
that's used to improve Python.


Hope this helps!


------------------------------------------------------------------------

(Advanced aside/rant: Implied string literal concatentation is actually a
sore spot for me.  I now personally think it was a design mistake to have
it in the Python language, because it's really common for folks to get
confused with it, and the efficiency benefit, in my opinion, isn't worth
the confusion.

The implicit string concatentation between the string literals is being
done at compile time, at the time when Python builds the bytecodes, and
not when the program is actually running.  We can see this with a concrete
example:

##################################################################
>>> import dis
>>> def t1():
...     return "hello " "world"
...
>>> def t2():
...     return "hello" + "world"
...
>>> def t3():
...     return "hello world"
...
>>> dis.dis(t1)
  2           0 LOAD_CONST               1 ('hello world')
              3 RETURN_VALUE
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
>>> dis.dis(t2)
  2           0 LOAD_CONST               1 ('hello')
              3 LOAD_CONST               2 ('world')
              6 BINARY_ADD
              7 RETURN_VALUE
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE
>>> dis.dis(t3)
  2           0 LOAD_CONST               1 ('hello world')
              3 RETURN_VALUE
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
##################################################################

What most people probably expect is that t1 and t2 are the same.  But what
this example is contrary to expectation: it shows us is that t1 and t3 are
the same.

It's one of the few places where the distinction between run-time and
compile-time exists in Python, and it's such a special case situation that
I can't imagine it really helping performance out in Python, where so much
else is done when we actually run the program.

And we already have the same kind of behavior out of:

######
>>> "hello\
... world"
'helloworld'
######

so I really don't see the need why implicit string literal concatenation
is in Python.  End of rant.)



More information about the Tutor mailing list