2011-01-10 5 views
1

Je me demande quels sont les avantages/inconvénients des dicts imbriqués par rapport à hacher un tuple en Python?Python - Dict imbriqué, ou hachage d'un tuple?

Le contexte est un petit script pour assigner des «ateliers» aux participants à une conférence.

Chaque atelier a plusieurs attributs (par exemple, semaine, jour, sujet, etc.). Nous utilisons quatre de ces attributs afin d'assigner des ateliers à chaque participant - à savoir chaque délégué aura également une semaine/jour/sujet, etc.

Actuellement, je suis en utilisant un dictionnaire imbriqué pour stocker mes ateliers:

workshops = defaultdict(lambda: defaultdict(lambda:defaultdict(lambda:defaultdict(dict)))) 

with open(input_filename) as input_file: 
    workshop_reader = csv.DictReader(input_file, dialect='excel') 

    for row in workshop_reader: 
     workshops[row['Week ']][row['Stream']][row['Strand']][row['Day']] = row 

return workshops 

Je peux ensuite utiliser la structure de données ci-dessus pour attribuer à chaque participant son atelier. Le problème est postérieur, j'ai besoin de parcourir tous les ateliers, et d'assigner un ID (cet ID est stocké dans un système différent), ce qui nécessite de déballer la structure couche par couche. Première question - Y a-t-il une autre façon de créer un index secondaire avec les mêmes valeurs, en utilisant une chaîne (nom de l'atelier) comme clé? C'est à dire. J'aurais toujours les dicts imbriqués à quatre niveaux, mais je pourrais aussi rechercher des entrées individuelles basées sur un simple nom. Deuxièmement, comment puis-je obtenir un effet similaire en utilisant les tuples comme clé? Y at-il des avantages que vous pouvez penser en utilisant cette approche? Serait-il plus propre ou plus facile à utiliser? (Tout ce déballage c'est un peu douloureux, et je ne pense pas que ce soit très accessible).

Ou existe-t-il d'autres structures de données que vous pourriez recommander et qui pourraient être supérieures/plus faciles d'accès/de manipulation?

Merci, Victor

Répondre

7
class Workshop(object): 
    def __init__(self, week, stream, strand, day, name): 
    self.week = week 
    self.stream = stream 
    self.day = day 
    self.strand = strand 
    self.name = name 

... 
for row in workshop_reader: 
    workshops['name'] = Workshop(...) 

Ce n'est si le nom est l'attribut unique des ateliers (qui est, aucun des ateliers avec des noms répéter).
En outre, vous pouvez facilement attribuer un ID à chaque objet Workshop dans le dictionnaire des ateliers.

+1

Ne serait-il pas préférable d'utiliser un tuple nommé puisqu'il ne s'agit que de données? –

+0

Hmm, c'est un bon point aeter =). J'aurais dû y penser ... lol. Et je suppose que je peux juste créer un dict des ateliers, pour faciliter la recherche rapide? Cependant, comment puis-je traverser la hiérarchie alors? Par exemple, avant de pouvoir accéder à la première couche pour obtenir tous les ateliers de la semaine 1, déroulez la couche suivante pour obtenir tous les ateliers de la semaine 1, du flux 1, etc. Est-il encore possible de naviguer avec des classes? – victorhooi

+0

Fondamentalement, si je vais en classe, y a-t-il un moyen facile de lister tous les ateliers pour une semaine/un brin/un flux donné - en supposant que Week/Strand/Stream sont des attributs d'instance dans la classe? – victorhooi

3

Généralement, si vous devez imbriquer des dictionnaires, vous devez utiliser des classes à la place. Les dictionnaires imbriqués deviennent compliqués à suivre lorsque vous déboguez. Avec les classes, vous pouvez distinguer différents types de dictionnaires, donc cela devient plus facile. :)

+0

Avec les classes, je ne suis pas sûr de pouvoir descendre dans la hiérarchie - avant, avec des Dicts imbriqués, je pouvais déballer la première couche pour obtenir tous les ateliers de la semaine 1, puis déballer l'un des dicts pour obtenir un stream etc. Je ne sais pas comment je peux faire ça avec seulement Class Workshop ... hmm ... – victorhooi

+0

@victorhooi: Vous descendez avec l'accès aux attributs. Donc, au lieu d'un adict ['foo'] = {} vous faites un anobject.foo = anotehrobject() –

+0

@Lennart Regebro: Hmm, je pense que je vais devoir repenser comment je stocke ces derniers. Parce que ce n'est pas comme "Weeks" va stocker une liste de "workshops", il va stocker un dict (?) Ou une autre collection, pour chaque flux. Et chaque flux aura une autre collection pour chaque brin. Et seulement alors nous arriverons aux ateliers réels. Dois-je créer une classe de classe, un cours de classe, un cours de classe - ou y a-t-il un meilleur moyen? – victorhooi