
The Idiomatic Way to Merge Dictionaries in Python - th
https://treyhunner.com/2016/02/how-to-merge-dictionaries-in-python/
======
lenzm
Seriously?! Just use solution 2, god forbid you have two lines of code to be
clear and accurate:

    
    
        >>> context = defaults.copy()
        >>> context.update(user)

------
anewhnaccount
This page is reasonable evidence that "one (obvious) way to do it" has gone
out the window, and that nowadays Python takes the kitchen sink approach like
many other languages, particularly those which have an "old" and a "new" way
of doing things. Examples are:

* Javascript (ECMAScript4, ECMAScript5 and ECMAScript6 all have different ways of iterating a collection! Not the mention the many utility libraries which implement quite basic things in different ways)

* PHP (Old school no-OO built-ins, <?php templating vs Java style OO PHP5+ and the SPL, )

* C++ ("C with classes" vs varying degrees of template magic, STL and Boost)

I'm beginning to feel quite sceptical about whether these types of changes are
actually worth it. % on strings was a little bit quirky but fine - I don't see
why .format() is better -- people are still going to encounter the first so
the damage is already done. Using either of the first two with .update() was
fine.

~~~
collyw
The first (or second) seem pretty obvious to me.

------
p4wnc6
I don't mean to be too critical because there was clearly a lot of effort in
this write-up, but as a serious question: what value does the post add that's
not already found at the huge and very popular Stack Overflow page [0] (that
this post even links to) about this subject?

Particularly, the answer by StackOverflow user `Aaron Hall` upvoted around 680
times [1], also deconstructs and provides eerily similar content as what this
post gives (for example, the poorness of the

    
    
        dict(x, **y)
    

solution and some performance comparisons).

I guess this post does mention itertools.chain and ChainMap ... though I would
almost never recommend using those if your goal is to merge two regular dicts.
Probably anyone reading the code is going to be baffled unless there was a
special reason why generators or ChainMap were needed -- these really don't
belong in the discussion; they're very different.

As someone who has used Python almost daily for the past 8 years, I also can't
help but feel let down when I read more stuff about being so-called
"pythonic." I especially hate it when I see discouraging criticisms on Stack
Overflow that seem to scare away newcomers because they didn't know you could
do a dict comprehension or something. The whole "pythonic" thing is waaayyyy
overrated. Just write code that is clean, and if you use a couple of extra
lines, or you loop over a range instead of a for-statement treating something
as an Iterator, so what, it really, really doesn't matter in most cases, and
you can always profile and fix the few cases where it does. It _certainly_
doesn't matter because of some subjective debates about what is more
"readable", like whether a dict-comprehension is "less readable" than a two-
line copy-and-update approach.

[0]
[http://stackoverflow.com/q/38987/567620](http://stackoverflow.com/q/38987/567620)

[1]
[http://stackoverflow.com/a/26853961/567620](http://stackoverflow.com/a/26853961/567620)

~~~
th
Thanks for the critique. I'm not sure I added much to that analysis on Stack
Overflow outside of headers, a few more opinions, and a little bit more
explanation. I mostly wrote to have something to link my students to because
this question has come up before and I didn't find any of the more
comprehensive SO answers to be easily digestible/skim-able.

The python-ideas thread from last year about using + on dictionaries was also
an inspiration. I don't recommend reading it in full (there's some painful
debating) but there were some really interesting concerns brought up on there
in regards to this particular problem.

In regards to newcomers being scared away by criticism on Stack Overflow: I
completely sympathize with this point of view. New Python programmers and new
programmers especially should not worry about what is "pythonic" until they've
become comfortable with their own Python programming abilities. Working and
readable code is most important, idiomatic code is simply icing on the cake.

I do however value discussions of what is "pythonic". I often discuss
"pythonic" in my classes to instill the idea that community norms change from
language to language and even between frameworks and projects.

I really hope the wording of this post didn't come off as elitist. If so, I
will certainly need to reconsider my wording for the next one.

~~~
p4wnc6
You do not come off as elitist in any way. Having your write-up available for
your students makes perfect sense, though I don't know that posting it to
Hacker News will result in much (but it doesn't seem like your target audience
anyway).

I think "pythonic" is a slippery slope. Many people take it too far and begin
to develop militant ideas of what "readability" means, or they do silly
things. For instance, I once heard a tale about someone needing to create
their own toolkit for handling paths in a certain project. It was just going
to a wrapper around the usual os.path tools, but would factor out a lot of the
team's repetitive code.

That person actually implemented __abs__ so that "abs(p)" resulted in the
absolute path for the path object p. Ugh!

The justification was that this is supposed to be more "pythonic" than just
writing a simple helper function. And of course, if you say that the
documentation about Python idioms or accepted understandings of what is
"pythonic" don't have anything to do with the choice to implement something as
a special method, the other person's response is just "yes it does" \-- their
interpretation is that this is what pythonic means. It's like having an
interpretation debate about the Bible or something. It means something
different to everyone, which makes it pretty useless as a centralized
standard.

If you apply good Haskell style, or good C style, or good Java style, to
writing Python, your code will be absolutely fine and perfectly readable even
in large enterprise codebases (perhaps more so depending on who else reads
it).

I think Google's C++ guide has the right idea. You should follow the _local_
conventions of the piece of code you're editing.

If you're working in a Python module where someone puts every function
argument on a new line (even if you're not near the 80 char limit) like this

    
    
        def foo(arg1,
                arg2,
                ...):
            # ...
    

then you should just also do that, and not waste time about whether this is
more Pythonic

    
    
        def foo(arg1, arg2,
                arg3, ...):
    

I think if the Python community trumps up this idea of pythonic, it just
alienates other people whose natural style (or the guides to their own main
languages) tell them differently.

Over time, Python developers will learn when it's better to use map than a
comprehension, how to style things, how avoid doing needlessly complicated
things like the __abs__ example above. You don't have to drill "pythonic"
stuff into them for that sort of clean code common sense to emerge, and you
certainly don't need to make it a major point of community pride or identity.

------
draw_down
I got a bad feeling when the simplest, most obvious, clearest solution that
solved the problem was rejected. Isn't that what Python is all about?

------
harlowja
U may also want to mention that #5 is pretty much violated in all of these if
say a nested dict (or really any other object that is by reference) is in
default or user.

    
    
      >>> x = {'a': {}}
      >>> y = x.copy()
      >>> y['a']['b'] = 'c'
      >>> x
      {'a': {'b': 'c'}}

~~~
Brainix
This is exactly what copy.deepcopy() is for. Although if you're headed down
this road, you're generally in for a bad time.

