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

Luigi Semenzato luigi at semenzato.com
Mon May 2 17:36:35 EDT 2016

Hello and sorry if this is an old and over-discussed topic.  I could
not find such discussions here.

This was discussed and rejected at https://bugs.python.org/issue16385,
but I am not convinced that the discussion presented all arguments
properly.  I tried reopening the bug at
http://bugs.python.org/issue26910, but was told I should discuss it
here instead.

The original problem description:

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.

These are the arguments presented in favor of the rejection, followed
by my rebuttals.

1. "An error is out of the question for compatibility reasons".  No
real rebuttal here, except I wonder if exceptions are ever made and
under what circumstances.  I should point out that a warning may also
create incompatibilities.

2. "There are ways to rewrite this as a loop on a list".  Yes of
course, but the entire point of the dictionary literal is to offer a
concise and convenient notation for entering a dictionary as program

3. "Being able to re-write keys is fundamental to Python dicts and why
they can be used for Python's mutable namespaces".  This is fine but
it applies to the data structure, not the literal constructor.

4. "A code generator could depend on being able to write duplicate
keys without having to go back and erase previous output".  Yes, but
it seems wrong to facilitate automated code generation at the expense
of human code writing.  For hand-written code, I claim that in most
(all?) cases it would be preferable to have the compiler detect key
duplications.  It is easier for an automated code generator to check
for duplications than it is for a human.

5. "There is already pylint".  True, but it forces an additional step.

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.

(additional search keywords: dict constructor, dict literal)

More information about the Python-ideas mailing list