web-dev-qa-db-ja.com

JSONオブジェクトの要素を削除する

オブジェクトのリストをループして、各オブジェクトから要素を削除しようとしています。各オブジェクトは新しい行です。オブジェクトに含まれる要素なしで、新しいファイルをそのまま保存しようとしています。これはおそらく簡単な作業であることは知っていますが、この仕事を得ることができないようです。誰かが手を差し出すことができれば感謝します。ありがとう。

{
"business_id": "fNGIbpazjTRdXgwRY_NIXA",
"full_address": "1201 Washington Ave\nCarnegie, PA 15106",
"hours": {
    "Monday": {
        "close": "23:00",
        "open": "11:00"
    },
    "Tuesday": {
        "close": "23:00",
        "open": "11:00"
    },
    "Friday": {
        "close": "23:00",
        "open": "11:00"
    },
    "Wednesday": {
        "close": "23:00",
        "open": "11:00"
    },
    "Thursday": {
        "close": "23:00",
        "open": "11:00"
    },
    "Saturday": {
        "close": "23:00",
        "open": "11:00"
    }
},
"open": true,
"categories": ["Bars", "American (Traditional)", "Nightlife", "Lounges", "Restaurants"],
"city": "Carnegie",
"review_count": 7,
"name": "Rocky's Lounge",
"neighborhoods": [],
"longitude": -80.0849416,
"state": "PA",
"stars": 4.0,
"latitude": 40.3964688,
"attributes": {
    "Alcohol": "full_bar",
    "Noise Level": "average",
    "Music": {
        "dj": false
    },
    "Attire": "casual",
    "Ambience": {
        "romantic": false,
        "intimate": false,
        "touristy": false,
        "hipster": false,
        "divey": false,
        "classy": false,
        "trendy": false,
        "upscale": false,
        "casual": false
    },
    "Good for Kids": true,
    "Wheelchair Accessible": true,
    "Good For Dancing": false,
    "Delivery": false,
    "Dogs Allowed": false,
    "Coat Check": false,
    "Smoking": "no",
    "Accepts Credit Cards": true,
    "Take-out": true,
    "Price Range": 1,
    "Outdoor Seating": false,
    "Takes Reservations": false,
    "Waiter Service": true,
    "Wi-Fi": "free",
    "Caters": false,
    "Good For": {
        "dessert": false,
        "latenight": false,
        "lunch": false,
        "dinner": false,
        "brunch": false,
        "breakfast": false
    },
    "Parking": {
        "garage": false,
        "street": false,
        "validated": false,
        "lot": true,
        "valet": false
    },
    "Has TV": true,
    "Good For Groups": true
},
"type": "business"

}

Hours要素に含まれる情報を削除する必要がありますが、情報は常に同じではありません。すべての日を含むものと、1日または2日の情報のみを含むものがあります。私が使用しようとしたコードは、私の問題で使用するために一日中検索できるPytonです。私はPythonにあまり熟練していません。任意の助けをいただければ幸いです。

import json

with open('data.json') as data_file:
data = json.load(data_file)
for element in data: 
        del element['hours']

申し訳ありませんが、コードを実行するとエラーが発生します。TypeError: 'unicode'オブジェクトはアイテムの削除をサポートしていません

8
Bradley

同じファイルを上書きしたいとします:

_import json

with open('data.json', 'r') as data_file:
    data = json.load(data_file)

for element in data:
    element.pop('hours', None)

with open('data.json', 'w') as data_file:
    data = json.dump(data, data_file)
_

dict.pop(<key>, not_found=None)は、要件を理解していれば、おそらくあなたが探しているものです。 hoursキーが存在する場合は削除され、存在しない場合でも失敗しないためです。

しかし、キー/値のペア全体を削除したいので、時間キーに数日が含まれているかどうかがあなたに違いをもたらす理由を理解できませんか?

さて、本当にdelの代わりにpopを使用したい場合、コードを機能させる方法を以下に示します。

_import json

with open('data.json') as data_file:
    data = json.load(data_file)

for element in data:
    if 'hours' in element:
        del element['hours']

with open('data.json', 'w') as data_file:
    data = json.dump(data, data_file)
_

[〜#〜] edit [〜#〜]したがって、ご覧のとおり、ファイルにデータを書き戻すコードを追加しました。別のファイルに書き込みたい場合は、2番目のopenステートメントでファイル名を変更するだけです。

お気付きかもしれませんが、データのクリーンアップフェーズでファイルが閉じられ、最後に上書きできるように、インデントを変更する必要がありました。

withは、コンテキストマネージャーと呼ばれるものであり、提供するもの(ここではdata_fileファイル記述子)は、そのコンテキスト内で利用可能です[〜#〜] only [〜#〜]これは、withブロックのインデントが終了するとすぐにファイルが閉じられ、コンテキストが終了し、ファイル記述子が無効/陳腐化することを意味します。

これを行わないと、ファイルを書き込みモードで開き、書き込む新しいファイル記述子を取得できません。

私はそれが十分に明確であることを願っています...

二次編集

今回は、これを行う必要があることは明らかです。

_with open('dest_file.json', 'w') as dest_file:
    with open('source_file.json', 'r') as source_file:
        for line in source_file:
            element = json.loads(line.strip())
            if 'hours' in element:
                del element['hours']
            dest_file.write(json.dumps(element))
_
24
Anthony Perot