2012-04-20 4 views
2
def function(s): 
if len(s) == 1: 
    print s[0], 
else: 
    function(s[1:]) 
    print s[0], 

function("1234") finit par imprimer 4 3 2 1Pourquoi cette sortie se produit-elle?

Pourquoi cela? Dans la fonction, évidemment la première condition n'est pas remplie. Dans l'autre condition, s[1:] est mis pour s, mais sa longueur n'est pas 1. Je ne vois pas comment quoi que ce soit en dehors de s[0] serait imprimé à l'écran. Il n'y a rien dans cette fonction qui semble imprimer s[1:], et encore moins dans le sens inverse. Je suis plutôt confus.

Répondre

1

Ceci est un cas de récursivité, vous appelez la fonction elle-même encore et encore avec des sous-chaînes de plus en plus courtes de l'entrée originale, jusqu'à ce qu'elle soit une chaîne de longueur 1 (la dernière dans l'entrée d'origine) il commence à l'imprimer puis à "dérouler" et à imprimer le reste de la chaîne à l'envers.

Jetez un oeil à ce code annotée:

def function(s): 
    if len(s) == 1: 
     print 'single:', s[0], # (A) this is where your first output is generated for a single character 
    else: 
     print 'calling function again with ',s[1:] 
     function(s[1:]) # (B) you call function again, i.e., your recursive call 
     print ' unwind->', s[0], # (C) the "unwinding" step, i.e, finish the rest 
           # of the function when you return from the recursive call 

la sortie que vous obtenez est:

calling function again with 234 
calling function again with 34 
calling function again with 4 
single: 4 unwind-> 3 unwind-> 2 unwind-> 1 

La première fois que vous appelez la fonction que vous laissez tomber par la clause else et ligne (B) vous appelez à nouveau la fonction, mais cette fois avec "234". Maintenant, la fonction redémarre mais avec "234" et de nouveau vous passez au else et appelez à nouveau la fonction, mais maintenant avec "34", la fonction s'exécute à nouveau, maintenant avec vous passez à la else une fois de plus et appelez la fonction avec juste "4" ... cette fois-ci, car elle est de longueur 1, vous l'imprimez (ligne A).

Maintenant vous revenez de cette fonction (le processus de déroulement) - et reprenez à l'endroit où vous étiez avant de faire votre appel récursif et vous imprimez le reste de la chaîne à l'envers en imprimant le premier caractère du caractère restant (ligne C).

La récursion peut être difficile à saisir la première fois que vous la rencontrez - c'est parfaitement normal. À un certain moment, il va cliquer et devenir clair. Vous voudrez peut-être faire quelques lectures sur le concept général et chercher des exemples clairs annotés (la plupart des livres de programmation/CS en auront).

Voici une courte vidéo YouTube qui explique récursivité en Python avec un exemple simple, espérons qu'il aide: http://www.youtube.com/watch?v=72hal4Cp_2I

+0

Je suis toujours perdu. Je ne comprends pas vraiment la récursion non plus. N'est-ce pas si vous appelez la fonction à nouveau, il continuerait à l'appeler et rien ne serait imprimé car la longueur de s [1:] n'est jamais 1? – VPNTIME

+0

@Omerta ce qui vous manque est que 's' est un * s' * différent chaque fois que' function' est appelé. Une fois que vous avez cela, 'len (s [1:])' fait, finalement, aller à 1. – lvc

+0

Merci Levon. Je l'obtiens vraiment maintenant. – VPNTIME

9
>>> def function(s): 
...  print 's is currently %r' % s 
...  if len(s) == 1: 
...   print s[0], 
...  else: 
...   function(s[1:]) 
...   print s[0], 
... 
>>> function("1234") 
s is currently '1234' 
s is currently '234' 
s is currently '34' 
s is currently '4' 
4 3 2 1 

Il est une fonction récursive, et il se dit encore une fois avant qu'il imprime s [0] si les éléments qu'il imprime sont inversés.

Voici un exemple qui pourrait être plus utile.

>>> def function(s): 
...  print 's is currently %r' % s 
...  if len(s) > 1: 
...   print 'calling function again with %r as s' % s[1:] 
...   function(s[1:]) 
...  print s[0], 
... 
>>> function('1234') 
s is currently '1234' 
calling function again with '234' as s 
s is currently '234' 
calling function again with '34' as s 
s is currently '34' 
calling function again with '4' as s 
s is currently '4' 
4 3 2 1 
1

Essayez de modifier la fonction comme ceci:

def function(s): 
    print 'Called with {}'.format(s) 
    if len(s) == 1: 
     print s[0] 
    else: 
     function(s[1:]) 
     print s[0] 

et l'exécuter. Vous verrez que chaque fois que vous appuyez sur function(s[1:]), vous suspendez cette "exécution" de function() et commencez une nouvelle exécution de function() à l'intérieur de celle qui est maintenant temporairement suspendue. Le nouvel appel à function() utilise une version raccourcie de la chaîne. Finalement, il est appelé avec un seul caractère et vous frappez la première condition.

L'appel d'une fonction depuis l'intérieur est appelé recursion.

0

Regardons la récursivité au travail.

  • D'abord, vous appelez la fonction s = "1234"
  • len (s) = 4 si vous prenez le reste
  • Vous fonction appelez récursive avec s[1:] ou "234"
    • maintenant , vous êtes en fonction avec s = "234"
    • len (s) = 3 donc vous prenez le reste
    • vous appelez la fonction récursive avec s[1:] ou "34"
      • Maintenant, vous êtes en fonction avec s = "34"
      • len (s) = 2 donc vous prenez le reste
      • Vous appeler la fonction récursive avec s[1:] ou "34"
        • Maintenant, vous sont en fonction avec s4"
        • len (s) = 1, de sorte que vous faites la première partie du si et et imprimer s[0] soit 4
        • vous revenez
      • De retour à l'appel précédent (s = "34") l'impression s[0], soit 3
      • Vous revenez
    • De retour à l'appel précédent (s = "234") l'impression s[0], soit 2
    • Vous retour
  • CReturning à l'appel précédent (s = "1234") l'impression s[0], à savoir 1
  • vous revenez
Questions connexes