Comment bien formater une liste de dictionnaires (ou d'instances) en Python

Lors du développement d'une application Web, il est courant d'implémenter un processus qui formate le résultat de l'exécution d'une requête SQL afin qu'il corresponde à la réponse de l'API.

Je pense que les données obtenues à la suite de l'exécution de la requête SQL sont principalement une liste d'instances définies par le pilote utilisé pour la connexion à la base de données, mais le processus de formatage de ces données est inopinément gênant. Je pense qu'il y en a beaucoup. (La plupart du traitement lui-même est simple, donc je pense souvent de cette façon.)

Dans cet article, j'ai examiné comment implémenter efficacement le processus de formatage des données ci-dessus.


Par exemple, si les données suivantes peuvent être obtenues à partir de la base de données Pensez à façonner ces données.


data_list = [
  {
    'user_id': 1,
    'group_name': 'GroupA',
    'user_name': 'user1',
    'email': '[email protected]'
  },
  {
    'user_id': 2,
    'group_name': 'GroupB',
    'user_name': 'user2',
    'email': '[email protected]'
  },
  {
    'user_id': 3,
    'group_name': 'GroupB',
    'user_name': 'user3',
    'email': '[email protected]'
  },
  {
    'user_id': 4,
    'group_name': 'GroupA',
    'user_name': 'user4',
    'email': '[email protected]'
  },
  {
    'user_id': 5,
    'group_name': 'GroupA',
    'user_name': 'user5',
    'email': '[email protected]'
  }
]

Les résultats attendus ont été regroupés par nom_groupe comme indiqué ci-dessous Il sera converti en données de format.

{
  "GroupA": [
    {
      "user_id": 1,
      "user_name": "user1",
      "email": "[email protected]"
    },
    {
      "user_id": 4,
      "user_name": "user4",
      "email": "[email protected]"
    },
    {
      "user_id": 5,
      "user_name": "user5",
      "email": "[email protected]"
    }
  ],
  "GroupB": [
    {
      "user_id": 2,
      "user_name": "user2",
      "email": "[email protected]"
    },
    {
      "user_id": 3,
      "user_name": "user3",
      "email": "[email protected]"
    }
  ]
}

J'ai examiné les deux modèles suivants comme méthode de mise en œuvre du traitement de mise en forme.

modèle 1

Je pense que le moyen le plus simple d'écrire est de regrouper les données une par une dans l'instruction for comme indiqué ci-dessous.

#L'argument est les données obtenues de la base de données
def sample1(data_list):
    
    result_dict = {}
    
    for data in data_list:
        
        group_name = data.get('group_name')
        
        # group_Considération lorsque le nom n'est pas enregistré
        if group_name not in result_dict:
            result_dict[group_name] = []
            
        # group_Générer un dictionnaire excluant le nom et l'ajouter à la liste
        result_dict[group_name].append({key:value for key, value in data.items() if key != 'group_name'})
        
    return result_dict
Motif 2

Ce processus de formatage peut également être implémenté à l'aide de la méthode Reduce.

from functools import reduce

#L'argument est les données obtenues de la base de données
def sample2(data_list):
    
    def accumulate(total, target):
        
        group_name = target.get('group_name')
        
        # group_Considération lorsque le nom n'est pas enregistré
        if group_name not in total:
            total[group_name] = []
            
        # group_Générer un dictionnaire excluant le nom et l'ajouter à la liste
        total[group_name].append({key:value for key, value in target.items() if key != 'group_name'})
        
        return total
        
    return reduce(accumulate, data_list, {})

Pour expliquer brièvement cette implémentation, la réduction peut passer une fonction comme premier argument, des données comme deuxième argument et une valeur initiale facultative comme troisième argument, elle a donc été obtenue à partir de la fonction de formatage des données (accumuler), DB. Data (data_list), un dictionnaire vide est passé comme valeur initiale. Ensuite, lorsque l'accumulation est appelée pour la première fois, un dictionnaire vide est passé à total, les premières données de data_list sont passées à la cible et la valeur de retour précédente est définie pour total après la deuxième fois. Devenir.


L'avantage d'écrire le modèle 1 est qu'il peut être implémenté par n'importe quel processus de formatage, mais l'inconvénient est qu'il doit être implémenté chaque fois qu'un processus de formatage comme celui-ci est requis (faible réutilisabilité). Je pense.

D'autre part, la manière d'écrire le motif 2 peut réduire la lisibilité lors de la mise en œuvre d'un traitement compliqué, mais le traitement de formatage est courant en changeant dynamiquement le nom de colonne référencé par la fonction de formatage de données. L'avantage est qu'il peut être converti.

N'y a-t-il pas non plus un problème de vitesse lors de l'utilisation de la réduction? Parce qu'il y avait un souci Au cas où, j'ai mesuré le temps nécessaire pour formater les données de 10000000 enregistrements pour chaque modèle. * Implémenté avec le notebook jupyter

%timeit sample1(data_list)
11.6 s ± 211 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit sample2(data_list)
12.3 s ± 290 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

À partir du résultat d'exécution ci-dessus, il a été constaté que la mise en œuvre utilisant réduire est un peu plus lente, mais même ainsi, il n'y a qu'une différence d'environ 1 seconde avec 10000000 données d'enregistrement, vous n'avez donc pas à vous soucier de la vitesse. pense.

De ce qui précède, en conclusion Je pense qu'il est réaliste de renoncer au traitement compliqué et d'utiliser l'instruction for tout en faisant en sorte que la politique de base à utiliser réduise autant que possible pour normaliser le traitement.

Recommended Posts

Comment bien formater une liste de dictionnaires (ou d'instances) en Python
Comment obtenir une liste d'exceptions intégrées pour python
Comment effacer un taple dans une liste (Python)
[Python] Comment mettre n'importe quel nombre d'entrées standard dans la liste
Comment écrire un type liste / dictionnaire de Python3
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
Comment réaliser quelque chose comme une liste de void * (ou de type de variante) dans Go?
Comment obtenir une liste de fichiers dans le même répertoire avec python
[Python] Comment créer une liste de chaînes de caractères caractère par caractère
Comment mélanger une partie de la liste Python (au hasard.shuffle)
Comment développer dans un environnement virtuel Python [Memo]
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
Comment vérifier en Python si l'un des éléments d'une liste est dans une autre liste
[Python] Comment convertir une liste bidimensionnelle en liste unidimensionnelle
Afficher une liste d'alphabets en Python 3
Comment obtenir stacktrace en python
Résumé de l'utilisation de la liste Python
Comment déterminer l'existence d'un élément sélénium en Python
Essayez d'obtenir la liste des fils du bulletin d'information (je n'aime pas) avec Python.
Comment transformer une chaîne en tableau ou un tableau en chaîne en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Comment supprimer plusieurs positions (index) spécifiées dans une liste Python
[Python] Comment supprimer des lignes et des colonnes dans une table (liste des options de méthode de dépôt)
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python (version non bloquante)
Comment incorporer des variables dans des chaînes python
Comment créer un fichier JSON en Python
Copiez la liste en Python
Résumé de l'utilisation de MNIST avec Python
[Python] Comment dessiner un histogramme avec Matplotlib
Comment supprimer les éléments en double dans la liste Python 3
Comment convertir / restaurer une chaîne avec [] en python
Comment obtenir le nombre de chiffres en Python
Comment mesurer le temps de traitement avec Python ou Java
[Python] Comment développer des variables dans une chaîne de caractères
Choses à noter lors de l'initialisation d'une liste en Python
[Python] Comment trier un dict dans une liste et une instance dans une liste
Regrouper par éléments consécutifs d'une liste en Python
Comment exécuter une commande à l'aide d'un sous-processus en Python
[Python] Comment afficher les valeurs de liste dans l'ordre
[Python] Comment utiliser la liste 1
Comment développer en Python
Comment compter le nombre d'occurrences de chaque élément de la liste en Python avec poids
Comment trouver le premier élément qui correspond aux critères de la liste Python
Comment découper un bloc de plusieurs tableaux à partir d'un multiple en Python
Comment sortir un document au format pdf avec Sphinx
Une histoire sur la façon de spécifier un chemin relatif en python.
Comment utiliser la méthode __call__ dans la classe Python
Comment importer des fichiers où vous le souhaitez en Python
Obtenez le nombre d'éléments spécifiques dans la liste python
Développer une bibliothèque pour obtenir la liste des collections Kindle en Python
Comment définir plusieurs variables dans une instruction Python for
J'ai essayé "Comment obtenir une méthode décorée en Python"
Comment afficher une liste des versions installables avec pyenv
Comparaison de l'utilisation des fonctions d'ordre supérieur dans Python 2 et 3
Comment obtenir une liste de liens à partir d'une page de wikipedia
Comment connecter le contenu de la liste dans une chaîne de caractères
[Python] Comment faire PCA avec Python