msg174507 - (view) |
Author: Albert Ferras (Albert.Ferras) |
Date: 2012-11-02 12:27 |
I normally use dictionaries for configuration purposes in python, but there's a problem where I have a dictionary with many key<->values and one of the keys is repeated.
For example:
lives_in = { 'lion': ['Africa', 'America],
'parrot': ['Europe'],
#... 100+ more rows here
'lion': ['Europe'],
#... 100+ more rows here
}
will end up with animal_lives_in['lion'] = 'Europe'. There's no way to detect that I've written a mistake in the code because python won't tell me there's a duplicated key assigned. It's easy to see when you have few keys but hard when you've got many.
I think it should atleast raise a warning when this happens.
|
msg174519 - (view) |
Author: Ramchandra Apte (Ramchandra Apte) * |
Date: 2012-11-02 14:32 |
This is an unavoidable behaviour of the hash tables (dictionaries)
I don't see much use cases of a warning.
|
msg174520 - (view) |
Author: Ramchandra Apte (Ramchandra Apte) * |
Date: 2012-11-02 14:34 |
Retract earlier statement. I didn't read the comment fully.
|
msg174522 - (view) |
Author: Ramchandra Apte (Ramchandra Apte) * |
Date: 2012-11-02 14:35 |
You should be using json for configuration purposes anyway.
This is low priority as only few programs use dictionaries with a gazillion keys.
|
msg174525 - (view) |
Author: Albert Ferras (Albert.Ferras) |
Date: 2012-11-02 14:49 |
I would use json, but it allows me to set list/strings, etc.. not python objects like I'd want
|
msg174526 - (view) |
Author: Albert Ferras (Albert.Ferras) |
Date: 2012-11-02 14:49 |
sorry: *it only allows me
|
msg174528 - (view) |
Author: Albert Ferras (Albert.Ferras) |
Date: 2012-11-02 14:51 |
also, it creates confusion when this happens
|
msg174530 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2012-11-02 14:57 |
It is a nice suggestion, but it is also probably a non-trivial change to the parser. If you want to try coming up with a patch we would consider it, but I suspect there is a limit to how much complexity we'd be willing to add to the parser code for this.
It would also be a backward incompatible change, so it could only go into a new release regardless.
(On the other hand Benjamin might take a look at this and say "oh, that's easy" and make some magic happen. You never know :)
|
msg174534 - (view) |
Author: Lukas Lueg (ebfe) |
Date: 2012-11-02 15:27 |
This could be avoided by
lives_in_init = (('lion': ['Africa', 'America']), ('lion': ['Europe']))
lives_in = {}
for k, v in lives_in_init:
assert k not in lives_in
lives_in[k] = v
del lives_in_init
Which is fast enough if executed only during module-loading
|
msg174535 - (view) |
Author: Benjamin Peterson (benjamin.peterson) * |
Date: 2012-11-02 15:49 |
An error is out of the question for compatibility reasons. I think the idea for a warning should be brought up on the python-ideas list. Silently rejecting duplicates has a lot of precedent, though. For example, set literals and the dict constructor:
>>> dict((("dfs", 2), ("dfs", 3)))
{'dfs' : 3}
|
msg174593 - (view) |
Author: Terry J. Reedy (terry.reedy) * |
Date: 2012-11-02 22:22 |
(Benjamin, did you mean 'silently accepting duplicates'?)
Without more use cases and support (from discussion on python-ideas), I think this should be rejected. Being able to re-write keys is fundamental to Python dicts and why they can be used for Python's mutable namespaces. A write-once or write-key-once dict would be something else.
As for literals, a code generator could depend on being able to write duplicate keys without having to go back and erase previous output. A lint-type code checker program could check for duplicate keys. OP: have you checked to see if PyLint or PyChecker or ... already do this? I think this is the appropriate place for such a thing. Lukas' code could be modified to do this also.
Keeping keys alphabetical (possibly within sections) should also solve this specialized problem.
|
msg174920 - (view) |
Author: Raymond Hettinger (rhettinger) * |
Date: 2012-11-05 17:07 |
FWIW, I agree with this rejection.
|
msg174955 - (view) |
Author: Lukas Lueg (ebfe) |
Date: 2012-11-06 06:29 |
PyLint or PyChecker can only do this if the keys are all simple objects like ints or strings. Consider a class with a custom __hash__
|
msg264683 - (view) |
Author: Gregory P. Smith (gregory.p.smith) * |
Date: 2016-05-02 23:40 |
Raising an error on duplicates also has precedent:
>>> dict(a=3, b=4, a=5)
File "<stdin>", line 1
SyntaxError: keyword argument repeated
|
msg337332 - (view) |
Author: Jonathan Fine (jfine2358) * |
Date: 2019-03-06 17:06 |
I mention this issue, and related pages, in
[Python-ideas] dict literal allows duplicate keys
https://mail.python.org/pipermail/python-ideas/2019-March/055717.html
It arises from a discussion of PEP 584 -- Add + and - operators to the built-in dict class.
Please send any follow-up to python-ideas (or this issue).
|
msg337676 - (view) |
Author: Rémi Lapeyre (remi.lapeyre) * |
Date: 2019-03-11 15:29 |
Guido van Rossum said in https://mail.python.org/pipermail/python-ideas/2019-March/055726.html: "this was an explicit design
decision that I made nearly 30 years ago".
I think the best way to avoid silently accepting such values would be to use @gregory.p.smith to use a function call to create the dictionary since duplicate keyword arguments raise an exception there.
I suggest to close this bug report since it works as expected.
|
msg337679 - (view) |
Author: Jonathan Fine (jfine2358) * |
Date: 2019-03-11 15:46 |
This is was closed and tagged as resolved in 2012. The status has not been changed since then.
Using dict(a=1, ...) provides a workaround, but only when the keys are valid as variable names. The general workaround is something like
helper([
(1, 'a'),
(2, 'b'),
#etc
])
The helper is necessary:
>>> [(1, 2)] * 5
[(1, 2), (1, 2), (1, 2), (1, 2), (1, 2)]
>>> dict([(1, 2)] * 5)
{1: 2}
|
|
Date |
User |
Action |
Args |
2022-04-11 14:57:37 | admin | set | github: 60589 |
2019-03-11 15:46:12 | jfine2358 | set | messages:
+ msg337679 |
2019-03-11 15:29:41 | remi.lapeyre | set | nosy:
+ remi.lapeyre
messages:
+ msg337676 versions:
+ Python 3.7, Python 3.8, - Python 3.4 |
2019-03-06 17:06:45 | jfine2358 | set | nosy:
+ jfine2358 messages:
+ msg337332
|
2016-05-02 23:40:18 | gregory.p.smith | set | nosy:
+ gregory.p.smith messages:
+ msg264683
|
2016-05-02 19:00:36 | r.david.murray | link | issue26910 superseder |
2012-11-06 06:29:20 | ebfe | set | messages:
+ msg174955 |
2012-11-05 17:07:11 | rhettinger | set | nosy:
+ rhettinger
messages:
+ msg174920 stage: resolved |
2012-11-02 23:15:47 | benjamin.peterson | set | status: open -> closed resolution: rejected |
2012-11-02 22:22:48 | terry.reedy | set | nosy:
+ terry.reedy messages:
+ msg174593
|
2012-11-02 17:48:32 | jcea | set | nosy:
+ jcea
|
2012-11-02 15:49:24 | benjamin.peterson | set | nosy:
+ benjamin.peterson messages:
+ msg174535
|
2012-11-02 15:27:27 | ebfe | set | nosy:
+ ebfe messages:
+ msg174534
|
2012-11-02 14:57:00 | r.david.murray | set | priority: normal -> low
type: behavior -> enhancement
title: evaluating dict with repeated keys gives no warnings/errors -> evaluating literal dict with repeated keys gives no warnings/errors nosy:
+ r.david.murray versions:
+ Python 3.4, - Python 2.7 messages:
+ msg174530 |
2012-11-02 14:51:21 | Albert.Ferras | set | messages:
+ msg174528 |
2012-11-02 14:49:56 | Albert.Ferras | set | messages:
+ msg174526 |
2012-11-02 14:49:04 | Albert.Ferras | set | messages:
+ msg174525 |
2012-11-02 14:35:18 | Ramchandra Apte | set | messages:
+ msg174522 |
2012-11-02 14:34:02 | Ramchandra Apte | set | messages:
+ msg174520 title: evaluating dict with repeated keys gives no warnings -> evaluating dict with repeated keys gives no warnings/errors |
2012-11-02 14:32:16 | Ramchandra Apte | set | nosy:
+ Ramchandra Apte
messages:
+ msg174519 title: evaluating dict with repeated keys gives no error/warnings -> evaluating dict with repeated keys gives no warnings |
2012-11-02 12:27:47 | Albert.Ferras | create | |