2008-11-27 9 views
1

J'ai le problème suivant:Problème avec expression booléenne avec une valeur de chaîne à partir d'une liste

# line is a line from a file that contains ["baa","beee","0"] 
    line = TcsLine.split(",") 
    NumPFCs = eval(line[2]) 
    if NumPFCs==0: 
    print line 

Je veux imprimer toutes les lignes du fichier si la deuxième position de la liste a une valeur == 0 .

j'imprimer les lignes, mais après que les événements suivants se produit: retraçage (appel le plus récent en dernier):

[ 'baaa', 'beee', '0', '\ n']

mais après je la prochaine erreur

ilation.py", line 141, in ? 
    getZeroPFcs() 
ilation.py", line 110, in getZeroPFcs 
    NumPFCs = eval(line[2]) 
    File "<string>", line 0 

Pouvez-vous s'il vous plaît me aider? grâce

What0s

Répondre

0

Votre question est un peu difficile à lire, mais en utilisant eval il n'y a certainement pas une bonne idée. Soit juste faire une comparaison de chaîne directe:

line=TcsLine.split(",") 
if line[2] == "0": 
    print line 

ou utiliser int

line=TcsLine.split(",") 
if int(line[2]) == 0: 
    print line 

Quoi qu'il en soit, vos mauvaises données vous échouez. Je recommande également de lire PEP 8.

+0

Une chaîne contenant '"0"]' convertit-elle de manière fiable? –

0

Il y a quelques problèmes que je vois dans votre segment de code:

  1. vous faites une hypothèse que la liste a toujours au moins 3 éléments
  2. eval soulèvera exception si la chaîne contenant n'est pas python valide
  3. vous dites que vous voulez un deuxième élément, mais vous accédez au 3ème élément.

Ceci est un moyen plus sûr de le faire

line=TcsLine.split(",") 
if len(line) >=3 and line[2].rfind("0") != -1: 
    print line 
+0

Cela signifie-t-il que si la troisième valeur est "101", elle sera imprimée? –

+0

je suis d'accord c'est mieux avec line [2] == "0" au lieu d'un rfind –

0

Je vous recommande d'utiliser une expression régulière pour capturer toutes les variantes de la façon dont 0 peut être spécifiée: avec des guillemets doubles, sans guillemets , avec des guillemets simples, avec des espaces supplémentaires à l'extérieur des guillemets, avec des espaces à l'intérieur des guillemets, comment vous voulez gérer les crochets, etc.

1

Laissez-moi vous expliquer un peu ce que vous faites ici.

Si vous écrivez:

NumPFCs = eval(line[2]) 

l'ordre d'évaluation est la suivante:

  • prendre le second caractère de la ligne de chaîne, par exemple une citation '"'
  • eval cette citation comme expression python, qui est une erreur.

Si vous écrivez plutôt comme:

NumPFCs = eval(line)[2] 

alors l'ordre d'évaluation est la suivante:

  • eval la ligne, la production d'une liste python
  • prendre le deuxième élément de cette liste, qui est une chaîne d'un caractère: "0"
  • une chaîne ne peut pas être comparée avec un nombre; c'est une erreur aussi.

En termes, vous voulez faire ce qui suit:

NumPFCs = eval(eval(line)[2]) 

ou, un peu mieux, comparer NumPFCs à une chaîne:

if NumPFCs == "0": 

mais les façons ce qui pourrait mal tourner sont presque innombrable. Vous devriez oublier eval et essayer d'utiliser d'autres méthodes: décomposition de chaîne, expressions régulières etc. D'autres ont déjà fourni quelques suggestions, et je suis sûr que d'autres suivront.

0

Il y a plusieurs façons de écorcher un chat, pour ainsi dire :)

Avant de commencer si, ne pas utiliser eval sur les chaînes qui ne vous appartiennent si la chaîne n'a jamais quitté votre programme; c'est-à-dire qu'il est resté dans un fichier, envoyé sur un réseau, quelqu'un peut envoyer quelque chose de méchant. Et si quelqu'un peut, vous pouvez être sûr que quelqu'un le fera.

Et vous pourriez vouloir regarder par-dessus votre format de données. Mettre des chaînes comme ["baa", "beee", "0", "\ n"] dans un fichier n'a pas beaucoup de sens pour moi.

La première et la plus simple serait de supprimer les éléments dont vous n'avez pas besoin et de comparer les chaînes. Cela fonctionnerait aussi longtemps que le « 0'cordes regarde toujours la même chose et que vous n'êtes pas vraiment après la valeur entière 0, seul le motif de caractères:

TcsLine = '["baa","beee","0"]' 

line = TcsLine.strip('[]').split(",") 
if line[2] == '"0"': 
    print line 

La deuxième façon serait de même à la première sauf que nous insultaient de la chaîne numérique à un nombre entier, ce qui donne la valeur entière que vous recherchez (mais l'impression « ligne » sans tous les guillemets):

TcsLine = '["baa","beee","0"]' 

line = [e.strip('"') for e in TcsLine.strip('[]').split(",")] 
NumPFCs = int(line[2]) 
if NumPFCs==0: 
    print line 

pourrait-il que la la chaîne est actuall y un tableau json? Ensuite j'obtiendrais probablement simplejson pour l'analyser correctement si j'exécutais Python < 2.6 ou simplement importer json sur Python> = 2.6. Transformez ensuite la chaîne '0' résultante en un entier comme dans l'exemple précédent.

TcsLine = '["baa","beee","0"]' 

#import json # for >= Python2.6 
import simplejson as json # for <Python2.6 

line = json.loads(TcsLine) 
NumPFCs = int(line[2]) 
if NumPFCs==0: 
    print line 
Questions connexes