Search code examples
pythonpython-3.xdictionaryordereddictionary

How to throw AssertionError for duplicate values in list of OrderedDict in python


I have a list of OrderedDict. The OrderedDict is a tuple of key/value pair:

dict_lists = [[OrderedDict([('name', 'Good check'), ('url',
              'https://www.facebook.com/'), ('lag', 10), ('tags',
              ['team:team 4', 'section 1', 'section 2']), ('headers',
              OrderedDict([('Location', 'http://facebook.com/')]))]),
              OrderedDict([('name', 'Bad check'), ('url',
              'https://www.google.com/'), ('lag', 5), ('tags',
              ['team:team 1'])]), OrderedDict([('name', 'Bad check'),
              ('url', 'https://www.microsoft.com/'), ('lag', 5), ('tags'
              , ['team:team 5'])])]]

I'm trying to throw an AssertionError when there are duplicate values for the "name" key.

Currently, it works for keys because I believe it throws an AssertionError for duplicate keys:

AssertionError: 'name' unexpectedly found in ['name', 'url', 'lag', 'tags', 'headers']

Code for duplicate keys:

import unittest
from collections import OrderedDict
    keys = []
            for dict_list in dict_lists:
                for dictionary in dict_list:
                    dict_keys = dictionary.keys()
                    for key in dict_keys:
                        self.assertNotIn(key, keys)
                        keys.append(key)

How do I get it work for duplicate values ( just for the "name" key)


Solution

  • Store your values for that key in a set, then test against that set:

    name_values = {}
    for dict_list in dict_lists:
        for dictionary in dict_list:
            if 'name' in dictionary:
                value = dictionary['name']
                self.assertNotIn(value, name_values)
                name_values.add(value)
    

    You should really also use a set for your keys. There is also no need to call the keys() method, looping over the dictionary directly gives you the keys too.

    If you want to combine the loops together, you could just test if the current key is equal to 'name':

    keys = {}
    name_values = {}
    
    for dict_list in dict_lists:
        for dictionary in dict_list:
            for key in dictionary:
                self.assertNotIn(key, keys)
                keys.add(key)
                if key == 'name':
                    value = dictionary[key]
                    self.assertNotIn(value, name_values)
                    name_values.add(value)
    

    Note that the fact that your dictionaries are ordered makes no difference to the solution here.