[Python-ideas] dictionary constructor should not allow duplicate keys

Steven D'Aprano steve at pearwood.info
Tue May 3 19:51:21 EDT 2016

Hi Luigi,

On Mon, May 02, 2016 at 02:36:35PM -0700, Luigi Semenzato wrote:

> lives_in = { 'lion': ['Africa', 'America'],
>              'parrot': ['Europe'],
>              #... 100+ more rows here
>              'lion': ['Europe'],
>              #... 100+ more rows here
>            }
> The above constructor overwrites the first 'lion' entry silently,
> often causing unexpected behavior.
> For context, someone ran into this problem in my team at Google (we
> fixed it using pylint).  I haven't seen any valid reason (in the bug
> or elsewhere) in favor of these constructor semantics.  From the
> discussions I have seen, it seems just an oversight in the
> implementation/specification of dictionary literals.  I'd be happy to
> hear stronger reasoning in favor of the status quo.

As far as I can see, you haven't specified in *detail* what change you 
wish to propose. It is difficult for me to judge your proposal when I 
don't know precisely what you are proposing.

Should duplicate keys be a SyntaxError at compile time, or a TypeError 
at runtime? Or something else?

What counts as "duplicate keys"?  I presume that you mean that two keys 
count as duplicate if they hash to the same value, and are equal. But 
you keep mentioning "literals" -- does this mean you care more about 
whether they look the same rather than are the same?

# duplicate literals, forbidden
d = {100: 1, 100: 2}

# duplicate non-literals, allowed
d = {100: 1, len("ab")*50: 2}

You keep mentioning "dictionary literal", but there actually is no 
such thing in Python. I think you mean a dict display. (Don't worry, I 
make the same mistake.) But the point is, a "dict literal" (display) can 
contain keys which are not themselves literals, as above. Those keys can 
have arbitrarily complex semantics, including side-effects. What do you 
expect to happen?


More information about the Python-ideas mailing list