从 Python 中的字典中的列表中删除一个元素
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"
}
]
}
我有一个像上面那样的字典,我想从里面的列表中删除带有 id=2
的元素。我浪费了半天时间想知道为什么 modify2
不能使用 del
操作。试过 pop
似乎有效,但我不完全理解为什么 del
无效。
有没有办法使用 del
删除或 pop 是解决此用例的理想方法?
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 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'}]}
我尝试寻找类似问题的答案,但没有找到解决我困惑的答案。
这是一种使用理解的方法。
例如:
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)
输出:
{'col': [{'id': 1, 'name': 'a'}, {'id': 3, 'name': 'c'}], 'tbl': 'test'}
在Python3中,你可以这样做:
test_dict = {**test_dict, 'col': [x for x in test_dict['col'] if x['id'] != 2]}
它不起作用的原因是您使用的 del 错误。
如果你有字典 d = {'a': [{'id':1}, {'id':2}]}
那么要删除你使用的字典的第二个元素 del d['a'][1]
这个 returns
d = {'a': [{'id':1}]}
因此,对于您的问题,您迭代以找到列表中 id 2 的位置,然后您可以简单地执行 del dict['col'][ix]
其中 ix 是列表中 id 2 的索引
del i
只是告诉解释器 i
(碰巧引用字典的任意本地 variable/name)不应再引用该字典。它不会改变该词典的任何内容。
这可以在 http://www.pythontutor.com/visualize.html 上可视化:
在 del i
之前。注意 i
引用第二个字典(用蓝线标注):
在del i
之后。请注意局部变量 i
是如何从局部命名空间(蓝色框)中删除的,但它引用的字典仍然存在。
与del i
相反(它修改了字典的引用),dict.pop(key)
修改了字典 .
您不能在 for 循环中删除迭代变量(i
)引用的元素
l = [1,2,3]
for i in l:
if i == 2:
del i
行不通。 l
仍将是 [1,2,3]
你可以做的是获取该元素的索引并使用索引删除
l = [1,2,3]
for idx, elem in enumerate(l):
if elem == 2:
del l[idx]
{
'tbl':'test',
'col':[
{
'id':1,
'name':"a"
},
{
'id':2,
'name':"b"
},
{
'id':3,
'name':"c"
}
]
}
我有一个像上面那样的字典,我想从里面的列表中删除带有 id=2
的元素。我浪费了半天时间想知道为什么 modify2
不能使用 del
操作。试过 pop
似乎有效,但我不完全理解为什么 del
无效。
有没有办法使用 del
删除或 pop 是解决此用例的理想方法?
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 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'}]}
我尝试寻找类似问题的答案,但没有找到解决我困惑的答案。
这是一种使用理解的方法。
例如:
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)
输出:
{'col': [{'id': 1, 'name': 'a'}, {'id': 3, 'name': 'c'}], 'tbl': 'test'}
在Python3中,你可以这样做:
test_dict = {**test_dict, 'col': [x for x in test_dict['col'] if x['id'] != 2]}
它不起作用的原因是您使用的 del 错误。
如果你有字典 d = {'a': [{'id':1}, {'id':2}]}
那么要删除你使用的字典的第二个元素 del d['a'][1]
这个 returns
d = {'a': [{'id':1}]}
因此,对于您的问题,您迭代以找到列表中 id 2 的位置,然后您可以简单地执行 del dict['col'][ix]
其中 ix 是列表中 id 2 的索引
del i
只是告诉解释器 i
(碰巧引用字典的任意本地 variable/name)不应再引用该字典。它不会改变该词典的任何内容。
这可以在 http://www.pythontutor.com/visualize.html 上可视化:
在 del i
之前。注意 i
引用第二个字典(用蓝线标注):
在del i
之后。请注意局部变量 i
是如何从局部命名空间(蓝色框)中删除的,但它引用的字典仍然存在。
与del i
相反(它修改了字典的引用),dict.pop(key)
修改了字典 .
您不能在 for 循环中删除迭代变量(i
)引用的元素
l = [1,2,3]
for i in l:
if i == 2:
del i
行不通。 l
仍将是 [1,2,3]
你可以做的是获取该元素的索引并使用索引删除
l = [1,2,3]
for idx, elem in enumerate(l):
if elem == 2:
del l[idx]