2017-08-08 4 views
0

次の形式のjsonファイルがあります。私は何をする必要があることは、「URI」はこれまでのところ、私は次の関数で立ち往生している「HTTP」python json remove()whileの条件の要素の問題

[ 
{ 
    "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'要素を削除しないということです。しかし、2回目のコードを実行すると、それが動作します。私はこれのために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

リストの反復処理中にリストを変更しないでください。そうすると予期しない動作が発生する可能性があります。反復しながら、

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

は、リストの内包を使用して、リストを変更しない:代わりに、あなたのJSONリストから要素をフィルタリングするために、リストの内包表記を使用することができます

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