120 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
description: |
 | 
						|
  ```python
 | 
						|
  from collections import defaultdict
 | 
						|
  from pprint import pprint
 | 
						|
  tree = lambda: defaultdict(tree)  # arbre = dictionnaire contenant un arbre
 | 
						|
  example = tree()  # création de l'arbre
 | 
						|
  example["A"]["A.1"]
 | 
						|
  example["A"]["A.2"]["A.2.1"]
 | 
						|
  example["B"]["B.1"]
 | 
						|
  def tree_to_dicts(tree):  # transformer en vrai dictionnaire
 | 
						|
      return {key: tree_to_dicts(tree[key]) for key in tree}
 | 
						|
  pprint(tree_to_dicts(example))
 | 
						|
  def add_path(tree, path):
 | 
						|
      for node in path:
 | 
						|
          tree = tree[node]
 | 
						|
  add_path(example, ["B", "B.2", "B.2.1"])
 | 
						|
  add_path(example, "B>B.2>B.2.2".split(">"))
 | 
						|
  pprint(tree_to_dicts(example))
 | 
						|
  ```
 | 
						|
---
 | 
						|
up::[[python tips]]
 | 
						|
link::https://gist.github.com/hrldcpr/2012250
 | 
						|
author::[[harold cooper]]
 | 
						|
title::"definir des [[structure de données.arbre|arbres]] avec les defaultdicts du module [[python module collections]]"
 | 
						|
 | 
						|
#s/informatique/langage/python
 | 
						|
 | 
						|
----
 | 
						|
Permet de définir la structure d'[[structure de données.arbre]] de manière simple, grace aux `defaultdicts` (module collections)
 | 
						|
 | 
						|
 | 
						|
# Définition
 | 
						|
```python
 | 
						|
from collections import defaultdict
 | 
						|
 | 
						|
# un arbre est un dictionnaire contenant d'autres arbres
 | 
						|
tree = lambda: defaultdict(tree)
 | 
						|
# on peut aussi utiliser :
 | 
						|
# def tree():
 | 
						|
#     return defaultdict(tree)
 | 
						|
 | 
						|
```
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# Créer
 | 
						|
 | 
						|
**Avec assignation**
 | 
						|
 - les feuilles sont des valeurs (pas des dictionnaires vides)
 | 
						|
 - [!] ne fonctionne pas avec toutes les fonctions listées ensuite
 | 
						|
```python
 | 
						|
users = tree()
 | 
						|
users['harold']['username'] = 'hrldcpr'
 | 
						|
users['handler']['username'] = 'matthandlersux'
 | 
						|
```
 | 
						|
 | 
						|
**Sans assignation**
 | 
						|
 - les feuilles sont des dictionnaires vides (avec clef mais pas valeur)
 | 
						|
 - [p] plus proche du modèle habituel pour les [[structure de données.arbre|arbres]] : les feuilles ont `null` comme enfant
 | 
						|
```python
 | 
						|
taxonomy = tree()
 | 
						|
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Felidae']['Felis']['cat']
 | 
						|
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Felidae']['Panthera']['lion']
 | 
						|
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Canidae']['Canis']['dog']
 | 
						|
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Canidae']['Canis']['coyote']
 | 
						|
taxonomy['Plantae']['Solanales']['Solanaceae']['Solanum']['tomato']
 | 
						|
taxonomy['Plantae']['Solanales']['Solanaceae']['Solanum']['potato']
 | 
						|
taxonomy['Plantae']['Solanales']['Convolvulaceae']['Ipomoea']['sweet potato']
 | 
						|
```
 | 
						|
 | 
						|
 | 
						|
# Afficher
 | 
						|
 | 
						|
Il faut d'abord transformer les arbres en vrais dictionnaires
 | 
						|
```python
 | 
						|
def tree_to_dict(tree):
 | 
						|
    # on transforme récursivement chaque branche de l'arbre en clef du dictionnaire
 | 
						|
    # le cas de base est automatique : quand le dictionnaire est vide
 | 
						|
    return {k: tree_to_dict(tree[k]) for k in tree}
 | 
						|
```
 | 
						|
 | 
						|
Ensuite, on peut simplement utiliser prettyprint :
 | 
						|
```python
 | 
						|
from pprint import pprint
 | 
						|
pprint(tree_to_dict(taxonomy))
 | 
						|
```
 | 
						|
```python
 | 
						|
{'Animalia': {'Chordata': {'Mammalia': {'Carnivora': {'Canidae': {'Canis': {'coyote': {},
 | 
						|
                                                                            'dog': {}}},
 | 
						|
                                                      'Felidae': {'Felis': {'cat': {}},
 | 
						|
                                                                  'Panthera': {'lion': {}}}}}}},
 | 
						|
 'Plantae': {'Solanales': {'Convolvulaceae': {'Ipomoea': {'sweet potato': {}}},
 | 
						|
                           'Solanaceae': {'Solanum': {'potato': {},
 | 
						|
                                                      'tomato': {}}}}}}
 | 
						|
```
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# Modifier
 | 
						|
 | 
						|
**Ajouter un chemin**
 | 
						|
 - on ajoute tout un chemin du graphe d'un seul coup
 | 
						|
```python
 | 
						|
def add_path(tree, path):
 | 
						|
    for node in path:
 | 
						|
        # for each node, you change the current subtree
 | 
						|
            # since you modify an object contained in the original tree, the whole tree is modified
 | 
						|
        tree = tree[path]
 | 
						|
 | 
						|
add_path(taxonomy,
 | 
						|
    'Animalia>Chordata>Mammalia>Cetacea>Balaenopteridae>Balaenoptera>blue whale'.split('>'))
 | 
						|
```
 | 
						|
```python
 | 
						|
# On peut aussi ajouter directement dans un sous-arbre
 | 
						|
add_path(taxonomy['Animalia']['Chordata']['Mammalia'],
 | 
						|
         "Cetacea>Balaenopteridae>Balaenoptera>blue whale".split('>'))
 | 
						|
```
 | 
						|
 |