2017-08-08 146 views
0

我有一个json文件,格式如下。我需要做的就是摆脱元素的整个字典里的“URI”不包含“HTTP”python json remove()元素问题一段时间条件

[ 
{ 
    "Exchange Name": "Standard & Poor's Indices", 
    "Number": 33.0, 
    "URI": "http://us.spindices.com/documents/additional-material/spdji-fixed-income-calendar-2016.xlsx", 
    "ref_id": "33_Standard_&_Poor's_Indices" 
}, 
{ 
    "Exchange Name": "ISE Mercury", 
    "Number": 36.0, 
    "URI": "follow OPRA", 
    "ref_id": "36_ISE_Mercury" 
}, 
{ 
    "Exchange Name": "Aequitas Neo", 
    "Number": 37.0, 
    "URI": "email for holidays", 
    "ref_id": "37_Aequitas_Neo" 
}, 
{ 
    "Exchange Name": "FINRA SPDS 144A", 
    "Number": 38.0, 
    "URI": "https://www.finra.org/industry/trace/trace-holiday-calendar", 
    "ref_id": "38_FINRA_SPDS_144A" 
} 
] 

到目前为止,我已经坚持了以下功能。这里的问题是remove()实际上并没有从字符串中移除一个'URI'元素。但是在我第二次运行代码之后,它就可以工作。我想我需要使用while循环来做这件事,但我该如何在这个设置中实现它。

def sys_validate_data(): 
    with open('./data_out/uniq_set.json') as jf: 
     json_decoded = json.load(jf) 
     for ix in json_decoded: 
      if "http" not in ix["URI"]: 
       json_decoded.remove(ix) 

     with open('./data_out/uniq_set.json', 'w') as fpw: 
      json.dump(list(json_decoded), fpw, sort_keys=True, indent=4) 
+5

不是。在迭代它时,不要*删除/添加/更改列表(以及任何其他集合)。 –

+0

如上所述,当您迭代列表并更改对象的计数时,会中断跟踪需要执行多少次迭代的循环,这可能会导致异常。 – Jaxi

+0

谢谢@WillemVanOnsem。这给了我一次机会再次实际地完成列表理解。对于未来的任何人来说,这里有一个很好的教程:http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/ 重要的是,列表理解将被格式化为: list_name = [表达;循环,条件] – katiepy

回答

2

不要在迭代列表时修改列表。这样做会产生意想不到的行为。相反,你可以使用列表理解从您的JSON列表过滤元件:

def sys_validate_data(): 
    with open('./data_out/uniq_set.json') as jf: 
     json_decoded = [ix for ix in json.load(jf) if "http" in ix["URI"]] 
     .... 
+0

我想他只是指以http开头的URI。但是,对于他的措辞('含有http'),这是正确的。 – Igle

+0

:D我们同时对此写了一条评论 – Igle

+0

请注意,在这种情况下,'in'隐含性会执行子字符串搜索。所以你可能会意外地漏掉一些误报,这取决于OP的措词。 – JoshuaRLi

1

使用列表理解和不改变列表而迭代:

validated_json = [entry for entry in json_decoded if entry['URI'].startswith('http')] 

扩展的例子:

def sys_validate_data(): 
    with open('./data_out/uniq_set.json') as jf: 
     json_decoded = json.load(jf) 
     validated_json = [entry for entry in json_decoded if entry['URI'].startswith('http')] 

     with open('./data_out/uniq_set.json', 'w') as fpw: 
      json.dump(validated_json, fpw, sort_keys=True, indent=4) 
+0

小挑剔:他说如果它不包含'“http”,那么删除该元素''如果它不是以''http''开头的话。所以你应该用'in'代替。 –

+0

谢谢@Igle。关于“http”,“startswith”或“in”,任何人都可以为我做这件事。虽然最好的做法总是正则表达式。 – katiepy