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!