1
votes

Comment raccourcir cette compréhension de liste imbriquée?

Cette question fait suite à celle-ci: Liste de compréhension et sortie . à 0x000002C392688C78>

J'ai été orienté pour créer une nouvelle question. J'ai quelques dicts dans un autre dict. Et ils deviennent parfois assez gros, puisque je les garde dans le journal, j'aimerais en limiter la taille à 30 'éléments' (clé: valeur).

J'ai donc essayé quelque chose comme ceci: (Dans l'exemple, je limite la taille à deux)

['A':['a1':[1, 2],'a2':[4, 5]], 'B':['b1':[0, 2], 'b2':[1, 3]]]

Le résultat que j'obtiens est le suivant: p >

[[1, 2], [4, 5], [0, 2], [1, 3]]

Voici ce à quoi je m'attendais:

main_dict = {
    'A':{
        'a1': [1,2,3],
        'a2': [4,5,6]
        },
    'B': {
        'b1': [0,2,4],
        'b2': [1,3,5]
        }
    }

print([main_dict[x][i][:2] for x in main_dict.keys() for i in main_dict[x].keys()])

Ou quelque chose comme ça. Il n'est pas nécessaire que ce soit exactement cela, mais j'ai besoin de savoir quelle valeur appartient à quel dict, ce qui n'est pas clair dans la sortie que je finis par obtenir.

Pour simplifier, tout ce que je veux, c'est couper les sous-dictionnaires dans le dictionnaire. Élégamment, si possible.


2 commentaires

[] est pour les listes, utilisez {} pour les dictionnaires


Donc, pour l'élément 'b1': [0,2,4] qui devient 'b1': [0, 2] , vous voulez simplement supprimer le 4 ?


5 Réponses :


1
votes

Essayez ceci:

print({key: {sub_key: lst[:2] for sub_key, lst in sub_dict.items()}
       for key, sub_dict in main_dict.items()})

Notez l'utilisation de {} (compréhension de dictée) au lieu de [] (compréhension de liste)


0 commentaires

-2
votes

J'ai réécrit mon code en fonction des commentaires fournis. Voir ci-dessous.

{'A': {'a1': [1, 2], 'a2': [4, 5]}, 'B': {'b1': [0, 2], 'b2': [1, 3]}}

Cela vous donnera quelque chose qui ressemble à ceci, et l'enregistrera dans une variable distincte.

my_dict = {}

for key, value in main_dict.iteritems():
    sub_dict = {}
    for sub_key, sub_value in value.iteritems():
        sub_dict[sub_key] = sub_value[:2] 
    my_dict[key] = sub_dict

print my_dict


1 commentaires

Ce n'est pas la sortie souhaitée par OP, et il modifie main_dict à la place dont ils ne veulent probablement pas car ils le font pour imprimer dans un fichier journal



1
votes

C'est une manière très simple de le faire en une seule ligne, sans modifier le dictionnaire d'origine:

print({key: {sub_k: ls[:2] for sub_k, ls in sub_dict.items()} for key, sub_dict in main_dict.items()})

Sortie:

{'A': {'a1': [1, 2], 'a2': [4, 5]}, 'B': {'b1': [0, 2], 'b2 ': [1, 3]}}

Votre essai d'origine utilisait la compréhension de liste [] , mais ce cas nécessite en fait une compréhension de dict {}.


2 commentaires

N'avait aucune idée que la compréhension dictée n'existait. Cela a parfaitement fonctionné, merci.


@ZeCarioca heureux de pouvoir vous aider! :)



0
votes

Une approche plus efficace consiste à utiliser des boucles for imbriquées pour supprimer la fin des sous-listes sur place:

{'A': {'a1': [1, 2], 'a2': [4, 5]}, 'B': {'b1': [0, 2], 'b2': [1, 3]}}

main_dict devient:

for d in main_dict.values():
    for k in d:
        del d[k][2:]


10 commentaires

Je crois que l'OP ne veut pas raccourcir le dictionnaire lui-même, juste le journal.


Pas idéal puisque OP veut simplement enregistrer les valeurs raccourcies, il veut probablement garder les valeurs d'origine intactes.


L'OP dit spécifiquement: «Pour faire simple, tout ce que je veux, c'est couper court les sous-dictionnaires à l'intérieur du dictionnaire. Élégamment, si possible. Il / elle ne dit pas qu'il / elle a besoin des valeurs d'origine pour quoi que ce soit d'autre. Pour moi, l'utilisation de l'expression raccourci signifie supprimer les éléments sur place.


Encore une solution facile même si vous vous trompez: new_dict = main_dict puis exécutez votre code sur (et imprimez) new_dict .


Si une nouvelle liste est nécessaire, il faut utiliser la compréhension. Mais étant donné la description du PO, je crois que la suppression sur place est ce que le PO souhaite.


@blhsing Dans la question liée, ils disent que le seul but de ceci est de raccourcir la sortie du journal des dicts qu'ils ont reçus - pour moi, cela implique qu'ils veulent faire autre chose avec le dict après l'avoir enregistré. Si la modification de main_dict est correcte, c'est la voie à suivre.


@ B.Shefter qui ne fera pas de copie profonde, juste une nouvelle référence au même dict, qui sera toujours modifié


@Phydeaux je vois. Je n'ai pas lu la question liée. Tu pourrais avoir raison. C'est alors à l'OP de décider du cas d'utilisation.


@Phydeaux Arrrgh. Vous avez raison, bien sûr. Puis-je voter contre mon propre commentaire?


Juste pour clarifier, je ne voulais pas modifier le dict, juste le court à des fins de journalisation. Cependant, j'aurais dû le préciser plus clairement. Merci à tous pour votre aide.



0
votes
q = []
for k,v in d.items():
   keys, values = v.keys(), v.values()
   values = (value[:2] for value in values)
   q.append((k,tuple(zip(keys,values))))

0 commentaires