Python - à l'aide d'une variable partagée dans une fonction récursive
Je suis en utilisant une fonction récursive pour trier une liste en Python, et je veux garder une trace du nombre de sortes/fusionne que la fonction est continue. Cependant, lorsque je déclare/initialisation de la variable à l'intérieur de la fonction, il devient une variable locale à l'intérieur de chaque appel de la fonction. Si je déclare la variable en dehors de la fonction, la fonction pense qu'il n'existe pas (c'est à dire n'a pas d'accès). Comment puis-je partager cette valeur à travers les différents appels de la fonction?
J'ai essayé d'utiliser le "global" variable de l'étiquette à l'intérieur et à l'extérieur de la fonction comme ceci:
global invcount ## I tried here, with and without the global tag
def inv_sort (listIn):
global invcount ## and here, with and without the global tag
if (invcount == undefined): ## can't figure this part out
invcount = 0
#do stuff
Mais je ne peux pas comprendre comment vérifier le statut non défini de la variable globale et de lui donner une valeur à la première récursivité appel (parce que sur toutes les récurrences il doit avoir une valeur et être défini).
Ma première pensée a été pour revenir à la variable de sortie de chaque appel de la fonction, mais je ne peux pas comprendre comment passer deux objets de la fonction, et j'ai déjà passer la liste de la récursion de tri de travail. Ma deuxième tentative pour résoudre ce problème je m'implique l'ajout de la variable invcount
à la liste je suis de passage comme le dernier élément avec un identifiant, comme "i27"
. Ensuite, j'ai pu seulement de vérifier la présence de l'identifiant (la lettre i
dans cet exemple) dans le dernier élément et pop() au début de l'appel de la fonction et ajouter de nouveau au cours de la récursivité. Dans la pratique, cela devient vraiment compliqué et il peut éventuellement travailler, je me demandais si il n'y est plus pratique, plus facile solution.
Est-il un moyen de partager une variable sans directement en passant/le retour?
listIn
ou crée et retourne une nouvelle liste?Eh bien, je suppose qu'il retourne une nouvelle liste, car j'ai créer un nouvel objet de liste de revenir, mais il utilise les mêmes éléments de la liste d'entrée et ajoute simplement dans l'ordre de tri de la nouvelle liste. En entrée une liste et la fonction des sorties de la liste dans l'ordre de tri. Je l'ai sortie de la liste dans l'ordre correctement maintenant, mais je viens d'avoir un problème de le faire pour compter le nombre de swaps ou des inversions dans le processus de commande, qui était à l'affectation dans mon algorithmes de la classe.
OriginalL'auteur Alium Britt | 2014-05-20
Vous devez vous connecter pour publier un commentaire.
Il ya un couple de choses que vous pouvez faire. Prendre votre exemple, vous devez le modifier comme ceci:
Mais cette approche signifie que vous devriez zéro
invcount
avant chaque appelinv_sort
.Donc en fait de son mieux pour revenir
invcount
, comme une partie du résultat. Par exemple, l'utilisation des n-uplets comme ceci:return this_list, this_integer
?Oui, bien sûr. Tout objet peut être une partie d'un tuple
Alright. Aussi, pourquoi exactement est-ce à dire que j'aurais à zéro la variable avec chaque appel de fonction? Je veux que le total en cours d'exécution, et avec les variables locales de la valeur est la force de le réinitialiser les paramètres par défaut. Vous dites que la variable globale est remise à 0 à chaque appel de fonction ou suggérez-vous que je fais ce que les meilleures pratiques?
Si vous voulez trier les deux listes, vous devez assigner invcount à zéro, de sorte première liste, magasin invcount valeur d'une autre variable. Puis définissez invcount à zéro, sorte de deuxième liste et stocker sa valeur. Sinon, après le tri de deux listes, vous aurez somme des appels de fonction de deux sortes.
Non, je ne veux trier une liste à la fois. C'est en fait une mise en œuvre de la fusion-algorithme de tri, de sorte que le code réel va quelque chose comme ceci:
left = whole[:middle] right = whole [middle:] left = inv_sort(left) right = inv_sort(right)
. Je veux leinv_count
à être partagé.OriginalL'auteur Alex Shkop
Une alternative pourrait être l'aide d'un argument par défaut, par exemple:
L'inconvénient de cette est que vos appels d'obtenir un peu moins soigné:
Mais cela ne signifie pas que la
invcount
est automatiquement remis à zéro à chaque fois que la fonction est appelée avec un seul argument (et aussi offre la possibilité d'injecter une valeur deinvcount
si nécessaire pour les tests:assert result, 6 == inv_sort(test, 5)
).invcount
variable, seulement en passant à revenir. Je vais devoir jouer avec elle et voir comment il fonctionne.Aussi, vous avez une virgule sur le côté gauche de l'opérateur d'affectation - est-ce à dire que je pourrais théoriquement retour d'un n-uplet et demandez à chaque valeur du tuple être automatiquement attribué à la variable correspondante sur le côté gauche?
oui, c'est exactement ce qui se passe -
invcount
retourne un 2-tuple qui est déballé pour deux séparez les noms par exemplel
et_
.Ok, je vais essayer de la fonction." Merci!
OriginalL'auteur jonrsharpe
Il n'y a pas une telle chose comme un "undefined variable" en Python, et vous n'en avez pas besoin.
En dehors de la fonction, définissez la variable à 0. L'intérieur de la boucle, utilisez le
global
mot-clé, puis incrémenter.global invcount
seulement se réserve le nom de ma variable dans l'espace de noms interne de la fonction? Quand je la modifier, il permet de changer la valeur externe de la variable avec le même nom?Je ne suis pas sûr de ce que vous demandez. Ce
global
ne est-à-dire à l'interprète de "dans le champ d'application actuel, le nom de "invcount" fait référence à la variable globale" - de sorte que toute cession de ce nom affecte la variable globale.Ok, c'est ce que je voulais savoir. Merci!
OriginalL'auteur Daniel Roseman
En supposant que vous n'avez pas besoin de connaître le nombre à l'intérieur de la fonction, je l'approche de ce à l'aide d'une fonction décorateur:
Vous pouvez maintenant décorer votre fonction récursive:
Et de vérifier ou de réinitialiser le
count
avant ou après l'appel à elle:@
symbole. Exactement ce que fait à l'aide de@
dire/faire?@count_calls
est sucre syntaxique pourinv_sort = count_calls(inv_sort)
- le "décorateur" fonction (count_calls
) doit prendre une fonction comme argument (f
) et le retour d'une fonction (func
).count
n'est pas une fonction, c'est un attribut defunc
, utilisé pour garder la trace du nombre de foisfunc
est appelé (et donc, commefunc
appelsf
, combien de foisf
est appelé).notez que j'ai juste corrigé une faute de frappe -
count_calls
en fait ne pasreturn func
!Alors, est-ce tout simplement en comptant le nombre de fois que la fonction est appelée? J'ai réellement besoin de connaître les résultats des différentes étapes à l'intérieur de la fonction, de sorte que le nombre de fois que j'appel la fonction ne sera pas directement lié à cette valeur. En fait, je peux appeler la fonction de nombreuses fois sans jamais l'incrémentation de l'intérieur de ma variable résultat
invcount
.dans ce cas, cette approche n'est probablement pas beaucoup d'utilisation pour vous!
OriginalL'auteur jonrsharpe