0
votes

Comment conserver le type d'éléments de liste après avoir été stockés dans un dictionnaire?

J'ai un dictionnaire imbriqué, qui est de la forme suivante.

Traceback (most recent call last):
  File "dmy.py", line 8, in <module>
    'foo': [0, a, a+b, 2*a, 2*(b+c)],
NameError: name 'a' is not defined

Il jette cette erreur:

import pickle

db = {'obj 1':
        {
        'a' : 1, 'b' : 2, 'c' : 3,
        'foo': [0, a, a+b, 2*a, 2*(b+c)],
        'bar': [c, c+a, c-b, 2*c, 2*a]
        },
    'obj 2':
        {
        'a' : 4, 'b' : 5, 'c' : 6,
        'foo': [0, a, a+b, 2*a, 2*(b+c), 0, 0],
        'bar': [c, c+a, c-b, 2*c, 2*a, 0, 0]
        },
}

with open("db.pkl", "wb") as pkl:
    pickle.dump(db, pkl)

print(db)

Y a-t-il quelque chose que je peut faire de telle sorte que j'obtienne la sortie pour dmy = db ['obj 1'] ['foo'] pour être [0, a, a + b, 2 * a, 2 * (b + c)] qui est une liste. Je comprends que ce que je fais n'est peut-être pas la bonne approche, mais j'ai besoin du contenu ensemble comme celui-ci.

Remarque: j'ai déjà essayé de convertir les éléments de la liste individuellement en chaînes, mais lors de l'analyse, je n'ai pas pu obtenir le contenu sous cette forme spécifiée, c'est-à-dire [0, a, a + b, 2 * a, 2 * (b + c)] .

Le lien le plus proche que j'ai pu trouver était ce lien Python - y a-t-il un moyen de stocker une operation (+ - * /) dans une liste ou comme une variable?


4 commentaires

mettre la liste entre guillemets "[0, a, a + b, 2 * a, 2 * (b + c)]" cela résoudra l'erreur


Mais alors comment puis-je conserver la valeur de «foo» en tant que liste après l'analyse? Je l'ai essayé et il est sorti comme un type de corde. Quoi qu'il en soit, je peux le reconvertir sous forme de liste sans faire beaucoup de manipulations de chaînes?


nous pouvons convertir en liste mais les variables de la liste seront toujours des chaînes. on ne peut pas changer les variables si on change on obtient l'erreur a is not defined


@RajuKomati ya exactement. J'ai modifié la question pour inclure plus d'informations. Je voudrais conserver les éléments de la liste tels quels.


3 Réponses :


1
votes

Le problème est que a , b et c sont membres de votre dict (pas encore existant). Ce ne sont pas des variables, donc

def transform(base, transform):
    base.update(transform(**base))
    return base

ne fonctionne pas.

Vous pouvez résoudre ce problème de la manière suivante:

    transform({'a' : 1, 'b' : 2, 'c' : 3, lambda base: {'foo': [0, base['a'], base['a']+base['b'], 2*base['a'], 2*(base['b']+base['c'])], 'bar': [base['c'], base['c']+base['a'], base['c']-base['b']b, 2*base['c'], 2*base['a']]})
    transform({'a' : 4, 'b' : 5, 'c' : 6, lambda base: {'foo': 0, base['a'], base['a']+base['b'], 2*base['a'], 2*(base['b']+base['c']), 0, 0], 'bar': [base['c'], base['c']+base['a'], base['c']-base['b']b, 2*base['c'], 2*base['a'], 0, 0]})


2 commentaires

Merci pour la réponse. J'ai compris votre point de vue, mais les informations doivent être stockées sous cette forme et récupérées, car elles font toutes partie du même élément dans une base de données. Il serait donc difficile pour moi de passer les valeurs requises avant de les obtenir. Je me demandais s'il y avait un moyen de le faire en Python.


@ snaire.stack non, il n'y a pas, du moins pas directement. Il y aurait la possibilité de créer un "dictionnaire de base", puis de la modifier en utilisant ses valeurs.



1
votes

Vous pouvez remplacer vos compréhensions de liste par des fonctions lambda et les décaper à l'aneth ( https://pypi.org / project / aneth / ) au lieu de cornichon:

import dill

db = {'obj 1':
        {
        'a' : 1, 'b' : 2, 'c' : 3,
        'foo': lambda a, b, c : [0, a, a+b, 2*a, 2*(b+c)],
        'bar': lambda a, b, c : [c, c+a, c-b, 2*c, 2*a]
        },
    'obj 2':
        {
        'a' : 4, 'b' : 5, 'c' : 6,
        'foo': lambda a, b, c : [0, a, a+b, 2*a, 2*(b+c), 0, 0],
        'bar': lambda a, b, c : [c, c+a, c-b, 2*c, 2*a, 0, 0]
        },
}

print(db)

pickled_db = dill.dumps(db)
unpickled_db = dill.loads(pickled_db)

print(unpickled_db)


0 commentaires

0
votes

Pour l'instant, j'ai réussi à le résoudre en utilisant eval . Le code que j'ai utilisé est donné ci-dessous.

{'obj 1': {'a': 1, 'b': 2, 'c': 3, 'foo': ['0', 'a', 'a+b', '2*a', '2*(b+c)'], 'bar': ['c', 'c+a', 'c-b', '2*c', '2*a']}, 'obj 2': {'a': 4, 'b': 5, 'c': 6, 'foo': ['0', 'a', 'a+b', '2*a', '2*(b+c)', '0', '0'], 'bar': ['c', 'c+a', 'c-b', '2*c', '2*a', '0', '0']}}

 [0, 1, 3, 2, 10]

Résultat:

import pickle

db = {'obj 1':
        {
        'a' : 1,
        'b' : 2,
        'c' : 3,
        'foo': ['0', 'a', 'a+b', '2*a', '2*(b+c)'],
        'bar': ['c', 'c+a', 'c-b', '2*c', '2*a']
        },
    'obj 2':
        {
        'a' : 4,
        'b' : 5,
        'c' : 6,
        'foo': ['0', 'a', 'a+b', '2*a', '2*(b+c)', '0', '0'],
        'bar': ['c', 'c+a', 'c-b', '2*c', '2*a', '0', '0']
        },
}

with open("db.pkl", "wb") as pkl:
    pickle.dump(db, pkl)
print(db)
with open("db.pkl", "rb") as pkl:
    db_pkl = pickle.loads(pkl.read())

a = db_pkl['obj 1']['a']
b = db_pkl['obj 1']['b']
c = db_pkl['obj 1']['c']
arr = db_pkl['obj 1']['foo']

arr_foo = []
for i in range(0, len(arr)):
    foo = eval(arr[i])
    arr_foo.append(foo)
print("\n", arr_foo)

Il ne conserve pas les noms de variables mais les calcule plutôt. Si quelqu'un a une manière plus propre, meilleure ou alternative de le faire, n'hésitez pas à modifier ou publier une réponse.


0 commentaires