Python,从循环中删除具有特定键的JSON元素

6
使用Python,我需要删除JSON数组中所有具有'name'键特定值的对象。但是,我不能从循环中这样做。
例如,我想删除以下输入中所有名称为'bad'的项目:
{
  'myArray' : [
    {
      'name' : 'good',
      'value' : '1'
    },
    {
      'name' : 'bad',
      'value' : '2'
    }
  ]
}

所以我使用以下Python测试案例:
myData = {'myArray': [{'name': 'good', 'value': '1'}, {'name': 'bad', 'value': '2'}]}

for a in myData['myArray']:
  if (a['name'] =='bad'):
    del a

print(json.dumps(myData))

我发现myData没有被改变。

我认为这是因为我试图在循环中删除一个迭代器,可能会被解释器视为风险操作,但Python没有报告任何运行时错误或警告。

在这种情况下,推荐采取什么方法呢?

谢谢!


我猜这是因为我试图删除循环的迭代器,这可能被解释器视为风险操作,但是Python没有报告任何运行时错误或警告。你并没有删除迭代器。实际上,你无法访问迭代器。你只是在a上执行了del操作,而a是对(隐式)调用迭代器的next方法所返回结果的变量的赋值。所以你删除了变量,但是在下一次迭代中,该变量会被重新创建。你想要改变你的集合,但你可能不应该在迭代时这样做。 - juanpa.arrivillaga
使用(嵌套)字典/列表推导式。在迭代对象时,永远不要尝试删除元素。 - smci
@Dmytro,这是一个最优解,因为它将在O(N)时间内运行,而如果从列表中删除,则需要O(N^2)的时间。在这里使用列表推导式也是惯用的,而且非常具有表现力/可读性。你也可以使用等效的for循环,但在这种情况下,[x for x in myData['myArray'] if x['name'] !='bad']非常简单易懂。 - juanpa.arrivillaga
好的,明白了。谢谢你的解释! - Dmytro
显示剩余2条评论
4个回答

4

在Python中使用enumerate()函数删除列表元素的一种方法Remove element from list when using enumerate() in python是循环遍历列表的副本[:],这也可以起到相同的效果:

for a in myData['myArray'][:]:
  if (a['name'] == u'bad'):
     myData['myArray'].remove(a)

谢谢大家!


1
使用(嵌套)字典/列表推导式。在迭代对象时不要尝试删除元素。
>>> [x for x in myData['myArray'] if x['name'] != 'bad']
[{'name': 'good', 'value': '1'}]

将结果分配给myData['myArray'],或任何您想要的名称。

0
你可以使用列表推导式。以下是参考文献。
new_list =  [obj for obj in myData['myArray'] if(obj['name'] != 'bad')] 
print new_list

0
myData = {'myArray': [{'name': 'good', 'value': '1'}, {'name': 'bad', 'value': '2'}]}

myData_clean = [x for x in myData['myArray'] if x['name'] !='bad']
myData_clean = {'myArray':myData_clean}
print(myData_clean)

输出:

{'myArray': [{'name': 'good', 'value': '1'}]}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接