How to raise an error if duplicates keys in a dictionary

I try to raise an error if the user enters a duplicate key in the dictionary. The dictionary is in the file, and the user can edit the file manually.

Example:

dico= {'root':{ 'a':{'some_key':'value',...}, 'b':{'some_key':'value',...}, 'c':{'some_key':'value',...}, ... 'a':{'some_key':'value',...}, } } 

new key 'a' already exists ...

How can I check dico and warn the user when loading dico from a file?

+6
python dictionary duplicates
source share
5 answers

Write a subclass of dict, override __setitem__ so that it throws an error when replacing an existing key; rewrite the file to use your new subclass constructor instead of the built-in dict built-in modules.

 import collections class Dict(dict): def __init__(self, inp=None): if isinstance(inp,dict): super(Dict,self).__init__(inp) else: super(Dict,self).__init__() if isinstance(inp, (collections.Mapping, collections.Iterable)): si = self.__setitem__ for k,v in inp: si(k,v) def __setitem__(self, k, v): try: self.__getitem__(k) raise ValueError("duplicate key '{0}' found".format(k)) except KeyError: super(Dict,self).__setitem__(k,v) 

then your file should be written as

 dico = Dict( ('root', Dict( ('a', Dict( ('some_key', 'value'), ('another_key', 'another_value') ), ('b', Dict( ('some_key', 'value') ), ('c', Dict( ('some_key', 'value'), ('another_key', 'another_value') ), .... ) ) 

using tuples instead of dicts to import the file (written using the {} notation, it will use the default dict constructor, and duplicates will disappear before the Dict constructor ever gets them!).

+12
source share

You will need a custom dict that can be rejected with a ValueError if the key is already present.

 class RejectingDict(dict): def __setitem__(self, k, v): if k in self.keys(): raise ValueError("Key is already present") else: return super(RejectingDict, self).__setitem__(k, v) 

Here's how it works.

 >>> obj = RejectingDict() >>> obj[1] = True >>> obj[2] = False >>> obj {1: True, 2: False} >>> obj[1] = False Traceback (most recent call last): File "<stdin>", line 1, in <module> File "rejectingdict.py", line 4, in __setitem__ raise ValueError("Key is already present") ValueError: Key is already present 
+4
source share

WRONG WAY
COME BACK

from x import dico not a good idea - you allow the USER to edit the code, which then runs blindly . You run the risk of getting simple typos, causing a syntax error, down to malicious things like import os; os.system("rm whatever"); dico = {} import os; os.system("rm whatever"); dico = {} import os; os.system("rm whatever"); dico = {} .

Do not succumb to the dict subclass. Write your own voice recorder downloader. It is not so difficult ... read the data file, check before each insert, if the key already exists; if this happens, write down the error message with significant things, such as the line number and the duplicate key and its value. In the end, if there were any errors, throw an exception. You may find that there is an existing module to do all this ... The Python supplied by ConfigParser aka configparser doesn't seem to be what you want.

By the way, you don’t have a single “root” key at the top level, is it pointless?

+3
source share

By default, Python's behavior is to silently overwrite duplicates when declaring a dictionary.

You can create your own dictionary class that will check if an element was already in the dictionary before adding new elements and then using it. But then you have to change the dico declaration in this file to one that duplicates, for example, a list of tuples.

Then, when you load this data file, you analyze it in your special "subclass" dict.

+1
source share

If you want to make sure that an error occurs when building a dict with duplicate keys, just use the Python keyword argument check:

 > dict(a={}, a={}) SyntaxError: keyword argument repeated 

If I am missing something, there is no need to subclass dict .

+1
source share

All Articles