11
votes

Comment s'assurer que les touches de dict python sont minuscules?

J'ai un dict que je veux convertir en Json à l'aide de SimpleJson.

Comment puis-je vous assurer que toutes les clés de mes dict sont minuscules? p>

    {
        "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": ""
    },


5 commentaires

S'assurer qu'ils sont minuscules, ils doivent être minuscules. Créez un dict avec des touches minuscules.


Qu'entendez-vous par «Assurez-vous»? Avez-vous et avez-vous des dicts existants et souhaitez-vous vérifier si toutes les clés sont minuscules? Ou les convertir tous en minuscule? Ou voulez-vous créer une sorte de dict qui permet uniquement aux touches minuscules (lorsque vous les insérez)?


Comme vous pouvez le constater dans l'exemple, certaines des clés ne sont pas minuscules. Je veux être sûr que chaque clé JSON est minuscule.


"Certaines des clés ne sont pas minuscules" Pourquoi pas? Votre éditeur était-il cassé? Qu'est-ce qui vous a arrêté de les résoudre?


Le dictionnaire est automatisé généré par django-piston et assurez-vous que les champs de modèles sont réécrivés avec le câble CLS_METHOD du gestionnaire, j'ai besoin de les mettre en majuscule. Lorsque je convertit le dictionnaire de Json, je dois m'assurer que la clé est tout en minuscule.


8 Réponses :


5
votes

Voici ma solution:

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


1 commentaires

Belle solution récursive, pour gérer le problème après "le fait".



29
votes
>>> 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}}

2 commentaires

Je ne saisis que pour que vous souhaitiez des dicts imbriqués et des listes traitées spécialement de votre réponse personnelle; Normalement, je manipulerais cela à un niveau différent.


Sur Python 3, vous pouvez utiliser la compréhension et vous aurez besoin de la dict (...) -> d = {k.lower (): v pour k, v dans d.Items ()}



4
votes

Puisque vous n'avez pas mentionné clairement ce que vous voulez faire:

Convertir toutes les touches en minuscule: P>

>>> for k in x.iterkeys():
    if k.islower():
        print k, 'True'
    else:
        print k, 'False'


1 commentaires

Le problème avec .iteritems () et .iterkeys () est qu'ils ne sont pas récursifs.



8
votes

Voici une solution qui interdit de définir une clé minuscule: xxx


3 commentaires

Ou, il suffit d'avoir __ settitem __ do dict .__ settitem __ (auto, clé.lower (), val) . Le problème avec cette approche en général est que le constructeur et .update n'utilise pas SETITEM - Vous devez travailler autour de cela, ou MODERCASEDICT ({ 'FOO': 1, 'Bar': 2}) n'agirais pas comme prévu (ne le masse pas pour mon chemin ou n'approuvera pas de typeError pour votre chemin).


Vous devez également veiller à ce que vous utilisez également de la masse inférieure pour chaque dicte imbriqué.


Cette mise en œuvre est incomplète car elle ne couvre pas correctement la création du dictionnaire. Voir Stackoverflow.com/a/27889931/99834 pour une solution de travail.



2
votes

Si vous voulez juste vérifier s'ils sont tous minuscules (votre libellé, en utilisant "Assurez-vous", n'est pas clair, mais je soupçonne que ce n'est pas ce que vous voulez), vous pouvez faire qui compacte en une ligne: xxx


0 commentaires

2
votes

Voici une solution complète xxx

ou si vous souhaitez voir le code: xxx


0 commentaires

1
votes

Vous pouvez utiliser python-benedict code> (A dict code> sous-classe) et standardisez strong> votre instance pour convertir toutes les touches de chaîne en Snake_Case .

{
    "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": ""
})


0 commentaires

1
votes

Une autre adaptation pour gérer les valeurs: xxx


0 commentaires