Karthik
Karthik

Reputation: 49

Iterate though a list of Dict Values and remove elements from that list

I have a list of dictionaries like below:

Dict1 = [{'Title': 'Title1', 'Attributes':['name1.50', 'name2.40', 'name1.90']}, 
         {'Title': 'Title2', 'Attributes':['name2.90', 'name1.40', 'name1.90']}]

I want to iterate through this dictionary and then iterate the 'Attributes' key in each dictionary to look for values starting with 'name1' and not having .90 in it, and remove it from the 'Attributes' key.

So the final dictionary should look like:

Dict1 = [{'Title': 'Title1', 'Attributes':['name1.90']}, 
         {'Title': 'Title2', 'Attributes':['name2.90', 'name1.90']}]

I have the iteration logic as

for item in Dict1:
    for name in item['Attributes']:
        if 'name1' in name:
            if name.split(".")[1] not '90':
                item['Attributes'].remove(name)

However I see that it doesn't remove all the values that are missing .90 in it. I tried some list comprehensions but did not help. I am new to python and coding in general, so I'm sure there is a much easier way to do this.

Upvotes: 0

Views: 1188

Answers (3)

Jai
Jai

Reputation: 3310

def solve():
    array = [{'Title': 'Title1', 'Attributes':['name1.50', 'name2.40', 'name1.90']}, {'Title': 'Title2', 'Attributes':['name2.90', 'name1.40', 'name1.90']}]

    for item in array:
        new_names = []
        for name in item['Attributes']:
            if '90' in name: new_names.append(name)
            elif 'name1' not in name: new_names.append(name)
        item['Attributes'] = new_names
    print(array)

solve()

Output: [{'Title': 'Title1', 'Attributes': ['name2.40', 'name1.90']}, {'Title': 'Title2', 'Attributes': ['name2.90', 'name1.90']}]

Upvotes: 0

you were very close to the right answer. In Python you can't manipulate values in a key/value pair. So instead, I tried this approach and this would produce your wanted output.

for x in Dict1:
    new_attributes = []
    print(x)
    for i in x['Attributes']:
        if i.split('.')[1] == '90':
            new_attributes.append(i)
    del x['Attributes'] #Not required. Can directly write the new list in the key
    x['Attributes'] = new_attributes

This creates a new list storing only the values you want, deletes the old Attributes key and creates a new one with the new list.

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140287

  • name.split(".")[1] not '90' is a syntax error, just use !=. Python is not only a cryptic language made of not, is, reduce, lambda...
  • item['Attributes'].remove(name) is done when you're iterating on the elements. That's bug prone: you can skip some elements

Best way is to rebuild your list of dictionaries in a list comprehension, and a dict comprehension with a filter for each dict:

Dict1 = [{'Title': 'Title1', 'Attributes':['name1.50', 'name2.40', 'name1.90']}, {'Title': 'Title2', 'Attributes':['name2.90', 'name1.40', 'name1.90']}]

new_dict_list = [{'Title':d['Title'], 'Attributes':[v for v in d['Attributes'] if v.endswith(".90")]} for d in Dict1]

result:

[{'Attributes': ['name1.90'], 'Title': 'Title1'},
{'Attributes': ['name2.90', 'name1.90'], 'Title': 'Title2'}]

with one less comprehension:

new_dict_list = []
for d in Dict1:
    values = [v for v in d['Attributes'] if v.endswith(".90")]
    new_dict_list.append({'Title':d['Title'], 'Attributes':values})

v.endswith(".90") could be 90 in v or not v.startswith('name1') and v.endswith('.90'), not sure of the exact condition, but I'll let that to the reader.

Upvotes: 2

Related Questions