2010-09-28 5 views
0

Je vais avoir beaucoup d'objets similaires avec des paramètres similaires. Exemple de paramètres d'un objet serait quelque chose comme:Utilisation de listes et de dictionnaires pour stocker des informations temporaires

nom, booléen, nombre et liste.

Le nom doit être une valeur unique parmi tous les objets, contrairement aux valeurs des paramètres booléens, numériques et de liste.

Je pourrais stocker les données sous forme de liste de dictionnaires je suppose. Comme ça:

list = [ 
    {'name':'a', 'bool':true, 'number':123, 'list':[1, 2, 3]}, 
    {'name':'b', 'bool':false, 'number':143, 'list':[1, 3, 5]}, 
    {'name':'c', 'bool':false, 'number':123, 'list':[1, 4, 5, 18]}, 
] 

Quel serait le meilleur moyen de vérifier si le nom unique existe dans la liste des dictionnaires, avant de créer un autre dictionnaire dans cette liste? Dois-je faire une boucle dans la liste et vérifier quelle est la valeur de list [i] [nom]? Ce qui serait le plus rapide et le moins mémorable pour conserver et traiter ces informations, en supposant que différentes listes similaires pourraient être traitées simultanément dans différents threads/tâches et que leur taille pourrait être comprise entre 100 et 100 000 dictionnaires par liste. Dois-je stocker ces listes dans la base de données au lieu de la mémoire?

Je comprends que peut-être je ne devrais pas pensé à optimiser (stocker les informations et les fils) avant que le projet fonctionne, donc s'il vous plaît, répondez à la question nom unique de recherche d'abord :)

Merci, Alan

Répondre

6

Si le nom est l'identifiant réel (unique) de chaque donnée interne, vous pouvez simplement utiliser un dictionnaire pour les données externes ainsi:

data = { 
    'a' : { 'bool':true, 'number':123, 'list':[1, 2, 3] }, 
    'b' : { 'bool':false, 'number':143, 'list':[1, 3, 5] }, 
    'c' : { 'bool':false, 'number':123, 'list':[1, 4, 5, 18] }, 
} 

Ensuite, vous pouvez facilement vérifier si la clé existe ou non.

Btw. Ne nommez pas vos variables list ou dict car cela écrasera les objets intégrés.

+0

+1 à l'utilisation des dictionnaires, bien que si vos données internes ('{'bool': true, 'number': 123, 'list': [1, 2, 3]}') sont toujours les mêmes Dans le même ordre, j'utiliserais une liste pour réduire le stockage. donc 'data = {'a': [true, 123, [1,2,3]], 'b': [faux, 143, [1,3,5]]}'. De toute façon, je suis d'accord que la façon la plus simple de vérifier serait juste si "potential_new_key dans les données: #do stuff" – nearlymonolith

+0

Awesome! Merci! N'a pas lu les docs python aussi près que je pouvais deviner :) –

+0

Oh et bien sûr je n'utiliserai pas de variables comme list ou dict ou boolean. Je les ai utilisés ici juste pour vous donner une idée du type de données que je prévois de stocker. –

0

Stocke les objets dans un dictionnaire avec le nom comme la clé:

objects = {'a' : {'bool':true, 'number':123, 'list':[1, 2, 3]}, 
      'b' : {'bool':false, 'number':143, 'list':[1, 3, 5]}, 
      'c' : {'bool':false, 'number':123, 'list':[1, 4, 5, 18]}} 

De cette façon, vous vous assurez que les noms sont uniques car toutes les clés du dictionnaire sont uniques. La vérification est un nom dans le dictionnaire est également facile:

name in objects 
+1

Pourquoi ne pas simplement appeler 'name in objects' plutôt que' bool (nom dans les objets) '? –

+0

J'ai ajouté bool() juste pour le rendre plus clair, mais je suppose que c'était le contraire. :-) Modification ... – Arlaharen

1

une fois que vous venez autour d'utiliser un dict au lieu d'une liste, la plus rapide pour effectuer la vérification que vous voulez est:

if 'newkey' not in items: 
    # create a new record 

puisque vous voulez être en mesure d'accéder à ces enregistrements à partir de plusieurs threads, je voudrais garder une collection de verrous. BTW, c'est le genre de chose que vous concevez au début car il fait partie de la conception de l'application et pas une optimisation. Maintenant, si vous souhaitez modifier vos éléments, vous pouvez utiliser les verrous pour le garder en sécurité.

locks = DictLock() 

with locks['a']: 
    # modify a. 

ou pour insérer un nouvel élément

with locks['z']: 
    #we are now the only ones (playing by the rules) accessing the 'z' key 
    items['z'] = create_new_item() 
+0

Merci. La nouvelle clef de dict est un moyen d'aller pour moi. Et merci pour la chose de verrouillage. Je ne vais pas utiliser même dict dans plusieurs threads cependant. Je voulais utiliser différents dicts dans différents fils. Un thread ne fonctionnera toujours que sur le même dictionnaire. Je vais toujours avoir besoin d'un moyen de garder une trace de la quantité de threads différents, en fonction de la façon dont les gros dictionnaires sont en cours de traitement, mais c'est un autre problème entièrement. Merci encore! –

0

Qu'est-ce que vous voulez est un dictionnaire « intrusive » - quelque chose qui ressemble à clés à l'intérieur des valeurs. Malheureusement, je ne connais aucune implémentation en Python. Le multi_index de Boost se rapproche.

0

Si vous ne souhaitez pas modifier la structure de données dont vous disposez, vous pouvez utiliser ce qui suit. Sinon, la réponse de Poke est la voie à suivre.

>>> my_list = [ 
... {'name':'a', 'bool':True, 'number':123, 'list':[1, 2, 3]}, 
... {'name':'b', 'bool':False, 'number':143, 'list':[1, 3, 5]}, 
... {'name':'c', 'bool':False, 'number':123, 'list':[1, 4, 5, 18]}, 
... ] 
>>> def is_present(data, name): 
...  return any(name == d["name"] for d in data) 
... 
>>> is_present(my_list, "a") 
True 
>>> is_present(my_list, "b") 
True 
>>> is_present(my_list, "c") 
True 
>>> is_present(my_list, "d") 
False 

Si vous passez any un itératives, il retourne vrai si l'un de ses éléments sont vrais.

(name == d["name"] for d in data) crée un générateur. Chaque fois que quelqu'un (dans ce cas, any) demande l'élément suivant, il le fait en obtenant l'élément suivant, d, de data et le transforme par l'expression name == d["name"]. Puisque les générateurs sont paresseux, c'est-à-dire que la transformation est effectuée lorsque l'élément suivant est demandé, ceci devrait utiliser relativement peu de mémoire (et devrait utiliser la même quantité de mémoire quelle que soit la taille de la liste).

Questions connexes