6
votes

Python dans l'ordre d'une trafûte à une liste plate

J'ai créé une méthode d'une classe Treenode que je veux retourner une liste plate d'un trershasal d'arbre dans l'arborescence

mon arbre d'échantillon est: p>

p>

La sortie Traverselle dans la commande doit être la suivante: [1, 1, 0, 2, 1, 3, 1, 1, 0] code> p>

mais je reçois: [2, 1, 1, 0, 1, 3, 1, 1, 0] p>

Voici mon code: P>

def in_order_list(self, r = []):
    hasLeft = self.left is not None
    hasRight = self.right is not None
    if self is None:
        return
    else:
        if hasLeft:
            self.left.in_order_list(r)
        r.append(self.value)
        if hasRight:
            self.right.in_order_list(r)
    return r


1 commentaires

Où est défini la liste de pré-commandes. Quelle est la structure de données du graphique?


4 Réponses :


2
votes

Ce pourrait être un problème avec l'argument par défaut pour r = []

exemple: xxx

python conserve la même liste sur plusieurs appels de fonction.

Essayez de faire le début de votre fonction quelque chose comme: xxx

Vous voudrez peut-être publier le reste de votre code, nous pouvons donc savoir ce que cette fonction Pre_Order fait .


1 commentaires

Bonjour @matt et @Campos, vous me demandez tous les deux sur ce que la fonction pré_order a mis en surbrillance mon erreur! La fonction devrait s'appeler in_order_list pas la fonction Pre_Order . Cette méthode fonctionne maintenant! Merci @ Campos.DDC pour la perspicacité sur plusieurs appels de la liste .



4
votes

au lieu d'appeler self.left / droite. code> dans code> strong> _Order_list () code>, vous appelez self.left / droite. code> pré code> strong> _Order_list () code>.

Pour accomplir ce que vous voulez faire un la fonction génératrice em> peut être meilleure (moins de consommation de mémoire et plus pythonique) que d'accumuler les valeurs dans une liste: p> xxx pré>

de cette façon, tu n'a pas t doit créer une liste si vous souhaitez uniquement itérer sur les valeurs suivantes: p> xxx pré>

L'algorithme fonctionne comme ceci: le générateur descend d'abord récursivement le long de la branche gauche de chaque nœud jusqu'à ce que Il frappe un sans sous-nœud gauche. Ensuite, il donne la valeur du nœud actuel. Après cela, il fait la même chose sur le sous-nœud droit, mais en commençant par le nœud actuel, pas le nœud racine. Si nous supposons qu'il n'y a pas de cycles dans l'arbre et pas de branches infinies, il y aura certainement des nœuds de feuilles, c'est-à-dire des nœuds sans sous-nœud gauche ou droit. IOw nœuds, pour lequel les deux cas de base ( self.left / droite sont Aucun code>) sont atteints. Par conséquent, les appels récursifs reviendront, espérons-le avant de sortir de la mémoire ou d'appuyer sur la limite de pile. P>

la boucle sur self.left / droite.in_ordre () code> est nécessaire au fait que l'appel à in_ordorder () code> renvoie est un générateur, d'où le nom fonction générateur em>. Le générateur retourné doit être épuisé d'une manière ou d'une autre, par exemple. à travers une boucle. Dans le corps de la boucle, nous reproduisons les valeurs sur un niveau, où ils sont reversés à nouveau, jusqu'à ce qu'ils atteignent le niveau supérieur. Là, nous utilisons les valeurs. P>

Si vous souhaitez extraire les nœuds eux-mêmes au lieu de leurs champs de valeur, vous pouvez le faire comme ceci: P>

for node in tree.in_order():
    whatever(node.some_other_attribute)


2 commentaires

Le générateur pour la gauche et la droite> rendement la valeur du nœud ou l'objet de nœud?


Essayer d'avoir la tête autour de ce qui se passe, je dirais pour gauche et pour les appels reconsives ils rendement l'objet nœud < / Code> - Est-ce exact?



1
votes

a) Tout d'abord comme indiqué par campos.ddc, avoir le [] être attribué la valeur au paramètre R est problématique. Pour plus de détails sur cette consultation Cette réponse sur Stackoverflow (c'est un très < / strong> Bug commun)

b) Il semblerait que votre test est redondant, si vous n'étaient pas en mesure d'appeler la méthode in_order_list (en supposant qu'il s'agisse d'une méthode dans un classe, et non une fonction autonome)

c) Le code pourrait être simplifié: xxx

d) questions probablement "devoirs" des questions probablement "devoirs", devrait être étiqueté comme tel. >: (


6 commentaires

Utilisez si r est Aucun non si non r pour tester contre Aucun NESS - sinon vous pourriez être confus. 0 . (Cela n'a pas d'importance dans ce cas particulier, mais est une bonne règle en général.)


Je suis en désaccord, l'attente est que R est une liste, donc la seule façon de pouvoir être évaluée à FALSE est si a) c'est non, ni b) est vide. Une liste contenant la valeur 0 sera évaluée à true, et si R est la valeur 0 qui indiquerait une erreur sur la partie de l'appelant. Dans les deux cas, sinon r plus concis et lisible (IMHO) que si r n'est pas:


Oui, mais mon point est que pour la comparaison contre les singletons, vous devez utiliser est . Pour moi, si non r me fait immédiatement penser à la non- [] boolean- false valeurs.


En d'autres termes, si r est aucun test contre la valeur immédiatement ci-dessus, il est donc clair que le seul moyen de réussir est si l'argument par défaut n'est pas remplacé. si non r ne teste pas contre cette valeur, vous devez donc penser à travers les cas pour voir que c'est correct.


"Il est donc clair que la seule façon de réussir est que l'argument par défaut ne soit pas remplacé" - ou l'utilisateur passe dans Aucun . Nous fractionnons les cheveux ici, je ne vois pas vraiment comme particulièrement vrai ou faux.


Merci@adamparkin. A) Comme Campos.DDC a mentionné un point inestimable - lisez votre lien. Ce ne sont pas des devoirs comme tels, car je ne prends pas un cours sur l'informatique, un projet personnel.



3
votes

Vous pouvez écrire ce genre de chose vraiment proprement comme un générateur et éviter de devoir gérer des listes et ajouter: xxx

par exemple: xxx


1 commentaires

Merci pour votre solution à l'aide d'un Generator Lecture à ce sujet, on dirait qu'un générateur s'occupe des variables locales entre les appels. Tout en utilisant un Generator est puissant, diriez-vous que c'est la mise en œuvre la plus classique pour quelque chose comme ça? C'est très élégant cependant. Merci