2012-10-30 10 views
0

Ainsi, le code ci-dessous prend une chaîne d'informations entrées (expression mathématique) et utilise la fonction find pour trouver l'un des opérateurs dans "*/+ -" et sépare la chaîne en conséquence .Python: Utilisation de la fonction find non dans l'ordre

def splitting1(z): 
    for operators in "*/+-": 
     if operators in z: 
      position1= z.find(operators) 
      position2= z.rfind(operators) 
      text_before_operators= (z[:position1]).strip() 
      text_after_operators= (z[(position1+1):(position2)]).strip() 
      return text_before_operators,text_after_operators 

Mon problème est que si j'ai une expression entrée tels que 3/5*7 puis position1 va d'abord trouver * avant de trouver /. Je veux que le code associe 'position1' à l'opérateur le plus à gauche. Existe-t-il un moyen d'omettre la priorité des opérateurs lors de l'utilisation des fonctions for/in? Sinon, existe-t-il un meilleur manipulateur de chaîne qui peut omettre l'ordre de priorité.

Remarque z est l'entrée. Et l'entrée est limitée à deux opérateurs au cas où cela créerait une ambiguïté.

+0

note: operator est un nom de module, ce qui peut être considéré comme une mauvaise pratique pour l'utiliser dans votre fonction. –

+0

merci, mal changer que – SeesSound

+0

si vous essayez d'évaluer une expression mathématique, ce n'est pas comment c'est fait. Lisez votre entrée de manière séquentielle, divisez-la en jetons (nombres, opérateurs) et placez les jetons dans les «positions» correctes en utilisant un algorithme d'analyse, comme le triage ou le top-down. – georg

Répondre

0

Vous effectuez l'itération sur */+-, le premier caractère trouvé est donc le premier qui a été renvoyé.

Vous voulez fondamentalement trouver les index de tous ces opérateurs et ensuite trouver le plus grand ou le plus petit. Essayez récrire cette fonction travailler pour l'autre côté de la chaîne:

def find_operator_right(text): 
    position = -1 

    for oper in '*/+-': 
     index = text.rfind(oper) 

     if index > position: 
      position = index 

    return position 

Une solution un peu plus Pythonic serait quelque chose comme ceci:

right_index = max(map(text.rfind, '+-/*')) 
+0

Vous vérifiez si 'index> position'. '-1' est juste le plus petit index qui peut être retourné par' find'. – Blender

+0

Alors dites-moi si j'ai bien compris: Votre code utilise d'abord text.rfind (oper) pour trouver le premier opérateur de "*/- +", si l'un d'entre eux est trouvé, il prend l'index, et assigne la valeur une variable appelée position. Mais si j'avais une expression comme 4 * 3/2, wouldnt il suffit de mettre l'index à 4, et ensuite définir la position = 4, Si nous avons remplacé text.rfind avec text.find et l'expression de 4 * 3/2 à 4/2 * 3 alors le même problème existerait comme misioned dans l'op? – SeesSound

+0

Ce code s'occupe de l'itération. C'est juste comme 'rfind', mais il cherche le caractère le plus à droite dans la liste des choix. – Blender

0

Il semble que vous essayez de lex, de sorte Je vous suggère de regarder dans des modules conçus spécialement à cet effet, par exemple ply.

.

Dire que, je pense que vous êtes sur la bonne voie pour cet exemple, mais il vous manque un peu récursion (pour faire un lexer plus général pour ces):

def splitting1(z): 
    for char in "*/+-": 
     if char in z: 
      position = z.find(char) 
      text_before_operator= (z[:position]).strip() 
      text_after_operator= (z[position+1:]).strip() 
      return (char, splitting1(text_before_operator), splitting1(text_after_operator)) 
    return ("number", z) 

Une façon de trouver la le plus à gauche opérateur quelle que soit la priorité à savoir Omettre la priorité des opérateurs, est de réorganiser ce que vous itérer sur:

def splitting2(z): 
    for char in z: 
     if char in "*/+-": 
      position = z.find(char) 
      text_before_operator= (z[:position]).strip() 
      text_after_operator= (z[position+1:]).strip() 
      return (char, splitting2(text_before_operator), splitting2(text_after_operator)) 
    return ("number", z) 

Notez ces fonctions renvoient un résultat différent à votre fonction d'origine.

+0

Vraiment ?? Donc j'ai juste dû changer les deux lignes, oh wow, merci. Mais pourquoi le code OP serait-il différent de ce second code que vous avez posté? Le code OP dit: pour les opérateurs dans "*/+ -" et si les opérateurs sont dans la chaîne z, alors ..... Et votre code dit pour les opérateurs dans la chaîne z, où les opérateurs sont définis par le suivant "si "code de ligne, alors ... – SeesSound

+0

Retour interrompt la boucle for, donc changer ce que vous itérez peut changer la valeur retournée ... si' z ''/* ''retourne en premier'' * '... 'dans la seconde retournera' '/' ... ' –

+0

changer l'ordre des lignes n'a rien changé ... – SeesSound

Questions connexes