12

simplejson を使用して JSON に変換したい辞書があります。

dict のすべてのキーが小文字であることを確認するにはどうすればよいですか?

    {
        "DISTANCE": 17.059918745802999, 
        "name": "Foo Bar", 
        "Restaurant": {
            "name": "Foo Bar", 
            "full_address": {
                "country": "France", 
                "street": "Foo Bar", 
                "zip_code": "68190", 
                "city": "UNGERSHEIM"
            }, 
            "phone": "+33.389624300", 
            "longitude": "7.3064454", 
            "latitude": "47.8769091", 
            "id": "538"
        }, 
        "price": "", 
        "composition": "", 
        "profils": {}, 
        "type_menu": "", 
        "ID": ""
    },

編集:私の質問を見てくれてありがとう。なぜこれが欲しかったのかを詳しく説明しなかったことを残念に思います。のパッチを当てることJSONEmitterでしdjango-pistonた。

4

8 に答える 8

29
>>> d = {"your": "DATA", "FROM": "above"}
>>> dict((k.lower(), v) for k, v in d.iteritems())
{'from': 'above', 'your': 'DATA'}
>>> def lower_keys(x):
...   if isinstance(x, list):
...     return [lower_keys(v) for v in x]
...   elif isinstance(x, dict):
...     return dict((k.lower(), lower_keys(v)) for k, v in x.iteritems())
...   else:
...     return x
...
>>> lower_keys({"NESTED": {"ANSWER": 42}})
{'nested': {'answer': 42}}
于 2010-11-19T09:57:26.420 に答える
8

小文字のキーの設定を禁止するソリューションは次のとおりです。

class LowerCaseDict(dict):
    def __setitem__(self, key, val):
        if not key.islower():
            raise TypeError, "%s key must be lowercase" % key
        dict.__setitem__(self, key, val)

ld = LowerCaseDict()
ld['g']='g'
于 2010-11-19T10:57:52.437 に答える
5

ここに私の解決策があります:

def lower_key(in_dict):
    if type(in_dict) is dict:
        out_dict = {}
        for key, item in in_dict.items():
            out_dict[key.lower()] = lower_key(item)
        return out_dict
    elif type(in_dict) is list:
        return [lower_key(obj) for obj in in_dict]
    else:
        return in_dict
于 2010-11-19T09:51:05.063 に答える
4

あなたがしたいことを明確に述べていないので:

すべてのキーを小文字に変換します。

>>> y = dict((k.lower(), v) for k, v in x.iteritems())

キーを確認します。

>>> for k in x.iterkeys():
    if k.islower():
        print k, 'True'
    else:
        print k, 'False'
于 2010-11-19T09:57:36.533 に答える
2

それらがすべて小文字であるかどうかを確認したいだけの場合(「ensure」を使用した言葉遣いは明確ではありませんが、これはあなたが望むものではないと思われます)、1行でコンパクトに行うことができます:

all(k.islower() for k in x.iterkeys())
于 2010-11-19T11:16:37.737 に答える
1

python-benedict(dictサブクラス) を使用してインスタンスを標準化snake_caseし、すべての文字列キーを.

from benedict import benedict

d = benedict({
    "DISTANCE": 17.059918745802999, 
    "name": "Foo Bar", 
    "Restaurant": {
        "name": "Foo Bar", 
        "full_address": {
            "country": "France", 
            "street": "Foo Bar", 
            "zip_code": "68190", 
            "city": "UNGERSHEIM"
        }, 
        "phone": "+33.389624300", 
        "longitude": "7.3064454", 
        "latitude": "47.8769091", 
        "id": "538"
    }, 
    "price": "", 
    "composition": "", 
    "profils": {}, 
    "type_menu": "", 
    "ID": ""
})

# convert all string keys to snake_case (nested dict keys included)
d.standardize()

そしてあなたのdict意志は次のようになります:

{
    "distance": 17.059918745802999, 
    "name": "Foo Bar", 
    "restaurant": {
        "name": "Foo Bar", 
        "full_address": {
            "country": "France", 
            "street": "Foo Bar", 
            "zip_code": "68190", 
            "city": "UNGERSHEIM"
        }, 
        "phone": "+33.389624300", 
        "longitude": "7.3064454", 
        "latitude": "47.8769091", 
        "id": "538"
    }, 
    "price": "", 
    "composition": "", 
    "profils": {}, 
    "type_menu": "", 
    "id": ""
})

インストール:pip install python-benedict

ドキュメント: https://github.com/fabiocaccamo/python-benedict

注:私はこのプロジェクトの作者です

于 2019-10-29T16:06:39.177 に答える
1

値を処理するための別の適応:


def lower_keys(x):
        if isinstance(x, str):
                return (x.lower())
        if isinstance(x, list):
                return [lower_keys(v) for v in x]
        elif isinstance(x, dict):
                return dict((k.lower(), lower_keys(v)) for k, v in x.items())
        else:
                return x
于 2019-11-21T21:11:23.320 に答える