1

I have the following problem:

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

I want to print all the lines from the file if the second position of the list has a value == 0.

I print the lines but after that the following happens: Traceback (most recent call last):

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

BUT after I have the next ERROR

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

Can you please help me? thanks

What0s

5 Answers 5

1

Let me explain a little what you do here.

If you write:

NumPFCs = eval(line[2])

the order of evaluation is:

  • take the second character of the string line, i.e. a quote '"'
  • eval this quote as a python expression, which is an error.

If you write it instead as:

NumPFCs = eval(line)[2]

then the order of evaluation is:

  • eval the line, producing a python list
  • take the second element of that list, which is a one-character string: "0"
  • a string cannot be compared with a number; this is an error too.

In your terms, you want to do the following:

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

or, slightly better, compare NumPFCs to a string:

if NumPFCs == "0":

but the ways this could go wrong are almost innumerable. You should forget about eval and try to use other methods: string splitting, regular expressions etc. Others have already provided some suggestions, and I'm sure more will follow.

Sign up to request clarification or add additional context in comments.

Comments

0

Your question is kind of hard to read, but using eval there is definitely not a good idea. Either just do a direct string comparison:

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

or use int

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

Either way, your bad data will fail you.

I'd also recomment reading PEP 8.

1 Comment

Does a string containing '"0"]' convert reliably?
0

There are a few issues I see in your code segment:

  1. you make an assumption that list always has at least 3 elements
  2. eval will raise exception if containing string isn't valid python
  3. you say you want second element, but you access the 3rd element.

This is a safer way to do this

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

2 Comments

Does that mean that if the third value is "101" it will be printed?
i agree this is better with line[2] == "0" instead of a rfind
0

I'd recommend using a regular expression to capture all of the variants of how 0 can be specified: with double-quotes, without any quotes, with single quotes, with extra whitespace outside the quotes, with whitespace inside the quotes, how you want the square brackets handled, etc.

Comments

0

There are many ways of skinning a cat, as it were :)

Before we begin though, don't use eval on strings that are not yours so if the string has ever left your program; i.e. it has stayed in a file, sent over a network, someone can send in something nasty. And if someone can, you can be sure someone will.

And you might want to look over your data format. Putting strings like ["baa","beee","0", "\n"] in a file does not make much sense to me.

The first and simplest way would be to just strip away the stuff you don't need and to a string comparison. This would work as long as the '0'-string always looks the same and you're not really after the integer value 0, only the character pattern:

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

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

The second way would be to similar to the first except that we cast the numeric string to an integer, yielding the integer value you were looking for (but printing 'line' without all the quotation marks):

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

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

Could it be that the string is actually a json array? Then I would probably go get simplejson to parse it properly if I were running Python<2.6 or just import json on Python>=2.6. Then cast the resulting '0'-string to an integer as in the previous example.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.