Home > Back-end >  Remove dictionary from list if it contains forbidden value
Remove dictionary from list if it contains forbidden value

Time:04-07

I have a list of dictionaries:

my_dicts = [
  {'name': 'aaa',
  'codename': 'bbbb',
  'type': 'cccc',
  'website': 'url1'},
  {'name': 'aaa2',
  'codename': 'bbbb2',
  'type': 'cccc2',
  'product_url': 'url2'},
  {'name': 'aaa2',
  'codename': 'bbbb2',
  'type': 'cccc2',
  'dop_url': 'url3'}
 ]

and a list:

my_list = ['url1', 'url3']

My goal is to have this output:

my_dicts = [
  {'name': 'aaa2',
  'codename': 'bbbb2',
  'type': 'cccc2',
  'product_url': 'url2'}
 ]

I want to find the most efficient way to remove the dictionaries where any value of said dictionary is in a list.

I tried this, but I'm getting the following error: RuntimeError: dictionary changed size during iteration.

for url in my_list:
        for e in my_dicts:
            for key, value in e.items():
                if value == url:
                    del e[key]

CodePudding user response:

You can use a list comprehension with all(), retaining only the dictionaries that do not have a key-value pair where the value appears in my_list:

[item for item in my_dict if all(url not in item.values() for url in my_list)]

This outputs:

[{'name': 'aaa2', 'codename': 'bbbb2', 'type': 'cccc2', 'product_url': 'url2'}]

CodePudding user response:

One approach is to have an outer loop that loops over each element in the list my_dicts and to have an inner loop that loops over each element of a given dict. For a given iteration of the outer loop, we store the index of the dict inside my_dicts inside the indices list if one of the values in the dict is contained in my_list. After completing our scan over my_dicts, using the indices we know which elements of my_dicts to remove.

indices = []
# locate dicts with a value that is in my_list
for index, elem in enumerate(my_dicts):
    for key in elem:
        if elem[key] in my_list:
            indices.append(index)
            break 
# remove dicts 
for i in reversed(indices):
    my_dicts.pop(i)

print(my_dicts)

Output

[{'name': 'aaa2', 'codename': 'bbbb2', 'type': 'cccc2', 'product_url': 'url2'}]

I hope this helps!

  • Related