简体   繁体   中英

Deleting an element from a list inside a dict in Python

{  
   'tbl':'test',
   'col':[  
      {  
         'id':1,
         'name':"a"
      },
      {  
         'id':2,
         'name':"b"
      },
      {  
         'id':3,
         'name':"c"
      }
   ]
}

I have a dictionary like the one above and I want to remove the element with id=2 from the list inside it. I wasted half a day wondering why modify2 is not working with del operation. Tried pop and it seems to be working but I don't completely understand why del doesn't work.

Is there a way to delete using del or pop is the ideal way to address this use case?

import copy

test_dict = {'tbl': 'test', 'col':[{'id':1, 'name': "a"}, {'id':2, 'name': "b"}, {'id':3, 'name': "c"}]}

def modify1(dict):
    new_dict = copy.deepcopy(dict)
    # new_dict = dict.copy()
    for i in range(len(dict['col'])):
        if dict['col'][i]['id'] == 2:
            new_dict['col'].pop(i)
    return new_dict

def modify2(dict):
    new_dict = copy.deepcopy(dict)
    # new_dict = dict.copy()
    for i in new_dict['col']:
        if i['id']==2:
            del i
    return new_dict

print("Output 1 : " + str(modify1(test_dict)))
print("Output 2 : " + str(modify2(test_dict)))

Output:

Output 1 : {'tbl': 'test', 'col': [{'id': 1, 'name': 'a'}, {'id': 3, 'name': 'c'}]}
Output 2 : {'tbl': 'test', 'col': [{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'b'}, {'id': 3, 'name': 'c'}]}

I tried looking for answers on similar questions but didn't find the one that clears my confusion.

在Python 3中,您可以这样做:

test_dict = {**test_dict, 'col': [x for x in test_dict['col'] if x['id'] != 2]}

del i just tells the interpreter that i (an arbitrary local variable/name that happens to reference to a dictionary) should not reference that dictionary any more. It does not change the content of that dictionary whatsoever.

This can be visualized on http://www.pythontutor.com/visualize.html :

Before del i . Note i references the second dictionary (noted by the blue line):

在此输入图像描述

After del i . Note how the local variable i is removed from the local namespace (the blue box) but the dictionary it referenced to still exists.

在此输入图像描述

Contrary to del i (which modifies the reference to the dictionary), dict.pop(key) modifies the dictionary .

This is one approach using a comprehension.

Ex:

data = {'tbl': 'test', 'col': [{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'b'}, {'id': 3, 'name': 'c'}]}

data['col'] = [i for i in data['col'] if i["id"] != 2]
print(data)

Output:

{'col': [{'id': 1, 'name': 'a'}, {'id': 3, 'name': 'c'}], 'tbl': 'test'}

The reason it is not working is that you are using del wrong.

If you have a dictionary d = {'a': [{'id':1}, {'id':2}]} Then to delete the second element of the dictionary you use del d['a'][1] this returns d = {'a': [{'id':1}]}

So for your problem you iterate to find the position of id 2 in the list and then you can simply do del dict['col'][ix] where ix is the index of id 2 in the list

You can't delete an element referenced by the iterating variable (the i )in the for loop

l = [1,2,3]
for i in l:
    if i == 2:
        del i

won't work. l will still be [1,2,3]

what you can do is get the index of that element and delete by using the index

l = [1,2,3]
for idx, elem in enumerate(l):
    if elem == 2:
        del l[idx]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM