2015-04-10 1 views
0

J'écris une chose de type octree en Python, et actuellement tout ce qu'il est capable de stocker est un ID. Cependant, je voudrais le changer afin qu'il puisse stocker un certain nombre de choses, et je ne suis pas sûr de savoir quelle serait la meilleure façon de prendre en compte cela pourrait être pour des milliers de valeurs. Si vous ajoutez des éléments au code, est-ce que le stockage en tant que liste normale sera correct et que le code sera dur dans les index, ou serait-il préférable de stocker en tant que dictionnaire pour obtenir les valeurs souhaitées?Vaut-il mieux stocker des valeurs de dictionnaire avec plusieurs éléments sous forme de listes ou de dictionnaires?

  1. =[ID, stuff1, stuff2...]
  2. ={'ID': num, 'stuff1': something, 'stuff2': something}

Si vous voulez que l'ID de la première façon, vous utilisez voxel_info[0], mais comme vous ajoutez plus de valeurs, il peut devenir plus compliqué, comme owner = voxel_info[4]; importantText = voxel_info[5] (où vous devez vous rappeler quel index se rapporte à quoi à tous les points dans le code), ou avec le dictionnaire, il serait beaucoup plus facile d'obtenir les valeurs si plus de choses ont été ajoutées. Le chemin du dictionnaire semble plus utilisable, mais il semble également que cela ralentisse le code et utilise plus de mémoire car il stocke des clés de texte pour des milliers de dictionnaires. De quelle façon recommanderiez-vous probablement?

Pour une idée de la façon dont les données sont stockées, c'est comme ça. Les éléments seront groupés si toutes les informations de bloc sont identiques, ainsi vous obtenez les différentes profondeurs. La partie BLOCKINFO est l'endroit où l'information est stockée, ce que je demande d'être une liste ou un dictionnaire.

OctreeData={ Depth: 2 
      Nodes: (1,1,1): {Depth:1 
          Nodes: (1,1,1): BLOCKINFO 
            (1,1,-1): {Depth: 0 
              Nodes: (1,1,1): BLOCKINFO 
                (1,1,-1): BLOCKINFO 
                (1,-1,-1): BLOCKINFO 
                etc 
            (1,-1,-1): BLOCKINFO 
            (-1,-1,-1): BLOCKINFO 
            (-1,-1,1): {Depth: 0 
               Nodes: etc 
            etc 
        (1,1,-1): BLOCKINFO 
        etc 
      } 
+3

Utilisez une classe ou d'un [ 'namedtuple'] (https://docs.python.org/2/library/collections.html#collections .namedtuple). –

+1

_ "mais il semble également que cela ralentisse le code et utilise plus de mémoire car il stocke des clés de texte pour des milliers de dictionnaires." _ Ne vous inquiétez pas jusqu'à ce que vous l'implémentiez réellement et observez un problème de performances. Tout est plus tôt une optimisation prématurée. Quoi qu'il en soit, des milliers de clés sont comme dix kilo-octets, ce qui ne vaut pas la peine d'être compliqué. – Kevin

+0

avec dictionnaire vous avez plus de contrôle à vos données. –

Répondre

2

Cela dépend vraiment de la taille de votre liste d'articles est et comment vous voulez y accéder

[[ID,stuff1,stuff2,stuff3],[ID,stuff1,stuff2,stuff3],...] 

prendra O(N) à la recherche par

également

[{'ID':'id','stuff':[1,2,3]},{'ID':'id','stuff':[1,2,3]}] 

prendra O(n) pour chercher par

{'ID1':['stuff1','stuff2','stuff3'], 
'ID2':['stuff1','stuff2','stuff3'], 
'ID3':['stuff1','stuff2','stuff3']} 

mais ne prendra O(1) à la recherche (en supposant que vous effectuez une recherche sur id)

mais vraiment je vous conseille d'utiliser une base de données (+ un ORM si vous êtes intelligent)

+0

Merci, arriver à ces valeurs n'est pas la partie la plus difficile, étant donné que c'est un octree, le dictionnaire se divise récursivement jusqu'à ce qu'il atteigne le point final où un bloc est (qui a besoin de cette information). meilleure façon d'écrire et de stocker tous ces points finaux :) – Peter

+0

si le temps de recherche n'est pas un problème, utilisez simplement ce que vous sentez comme modèle le meilleur ... un dict, une liste, une classe personnalisée, etc –

+0

Ouais, c'était plus Je me demandais si les dictionnaires ralentiraient sérieusement les choses, mais les gens ont suggéré des tuples nommés qui sonnent comme le meilleur pari, puisque je n'ai pas besoin de changer quoi que ce soit une fois qu'il est écrit :) – Peter

1

Il n'y a rien de mal à mélanger à la fois dicts et lists.

Ceci peut vous donner des solutions plus élégantes qu'une simple structure.

my_data = [ 
    { 'ID' : 1, 'stuff' : ['stuff1', 'stuff2', 'stuff3']}, 
    { 'ID' : 2, 'stuff' : ['stuff1', 'stuff2', 'stuff3']}, 
    { 'ID' : 3, 'stuff' : ['stuff1', 'stuff2', 'stuff3']}, 
] 

ou ...

my_data = { 
    'ID1' : [ 'stuff1', 'stuff2', 'stuff3'], 
    'ID2' : [ 'stuff1', 'stuff2', 'stuff3'], 
    'ID3' : [ 'stuff1', 'stuff2', 'stuff3'], 
} 

Personnellement, je pencherais pour l'option 1. Pourquoi? Chaque dictionnaire de la liste a la même structure. Cela le rend plus propre et plus facile à comprendre.

En ce qui concerne la recherche, vous pouvez utiliser le filtre:

from functools import partial 

def custom_filter(data, filter_value=None): 
    if data['ID'] == filter_value: 
     return True 
    return False 

filter_on = 1 
print filter(partial(custom_filter, filter_value=filter_on), my_data) 
+0

Je ne suis pas sûr de comprendre votre argument option 1, les deux fourniraient une structure cohérente et l'option 2 vous permet d'accéder à des éléments pour un ID spécifique en 'O (1)', vs rechercher une liste d'ID 'O (n)' – AChampion

+0

Merci, stuff1, stuff2, etc était juste pour signifier différentes valeurs haha, avec cela étant stocké dans un octree, tout est stocké récursivement, donc les valeurs sont le point final, et toutes sont séparées les unes des autres :) Je vais mettre à jour la question haha – Peter