2013-04-18 5 views
2

J'essaye d'écrire une fonction récursive de Python 3 qui me dira si un entier est dans une liste imbriquée. Je ne suis pas sûr comment je peux rendre mon code retourner True s'il le trouve dans la liste, et False s'il ne le trouve pas dans la liste. Lorsque j'imprime le résultat de ma boucle, je reçois un tas deRécursivité Python, comment se fait-il que ma fonction ne fonctionne pas?

false 
false 
false 
false 
true 
false 
false 
false 

etc. Mais, il retourne faux parce que le dernier appel était faux, même si je veux qu'il revienne vrai. Comment puis-je réparer cela?

Voici mon code:

def nestedListContains(NL, target):  
    if(isinstance(NL, int)): 
     return NL  

    for i in range(0, len(NL)): 
     return (nestedListContains(NL[i], target) == target) 

    return False 

Et voici comment je l'appeler

print(nestedListContains([[3], [4,5,7], [[[8]]]], 8)) 

EDIT: Cela semble fonctionner pour moi, mais il semble plutôt ghetto:

def nestedListContains(NL, target):  
    if(isinstance(NL, int)): 
     if(NL == target): 
      return 1 
     return 0 

    x = 0 

    for n in NL: 
     x += nestedListContains(n, target) == 1   

    return x != 0 
+0

Outre le problème récurrent, votre scénario de base semble erroné. Quand vous descendez à un 'int', au lieu de retourner true si elle est égale à la cible, vous renvoyez le' int' lui-même. Cela signifie qu'en fin de compte, vous retournerez true s'il y a des éléments non-zéro dans la liste, false sinon. – abarnert

+0

Vous pourriez également vouloir penser à la robustesse ici. Si NL contient des non-séquences non-int, cela déclenchera un 'TypeError', ce qui est probablement bien, mais s'il contient des chaînes, il ira dans la récursion infinie (qui finira par déclencher une exception quand il frappe le limite), ce qui peut ne pas être bon. – abarnert

+0

Aussi: Pourquoi ne pas simplement supprimer la vérification 'int', et faire juste' si NL == target: return True'? Si 'target' est toujours un' int', cela aura exactement le même effet. Mais il vous permet de rechercher d'autres types (y compris des objets qui peuvent être égaux à un 'int' mais n'en sont pas un). Et c'est plus simple. – abarnert

Répondre

4

Le résultat est return que ce soit True ou non. Vous pouvez faire quelque chose comme ceci:

def nestedListContains(NL, target):  
    if isinstance(NL, int): 
     return NL == target 

    for n in NL: 
     result = nestedListContains(n, target) 

     if result: 
      return result 

    return False 
+1

Voulez-vous dire 'nestedListContains (n, target) == target'? –

+0

@LevLevitsky: Oui, merci. – Blender

+0

nestedListContains def (NL, cible): if (isinstance (NL, int)): if (NL == cible): retour 1 return 0 x = 0 pour n en NL: x + = nestedListContains (n, target) == 1 return x! = 0 Votre méthode ne fonctionnait toujours pas pour moi Je suis en train de faire des choses dans le ghetto, mais ça semble fonctionner, existe-t-il une alternative? ? – Jason

5

Ma tentative:

def contains(lst, target): 
    if isinstance(lst, int): 
     return lst == target 

    return any(contains(x, target) for x in lst) 
0

En utilisant la saisie de canard pour la solution de @ Gatto

def contains(lst, target): 
    try: 
     return any(contains(x, target) for x in lst)   
    except TypeError: 
     return lst == target 
+1

Peut entrer en récurrence infinie si 'lst' a une chaîne. Je pense qu'il vaut mieux vérifier s'il y a un attribut '__iter__'. – gatto

+0

très vrai, merci pour l'aperçu supplémentaire. – dansalmo

Questions connexes