tags:

views:

74

answers:

5

I have the following lines in a file where I want to take the third column; In the file I don't have the numbers column:

  1. Red; Blue; Green; White; Orange;
  2. Green; White; Orange;
  3. Blue; Green; White;
  4. Red; Blue; Green; White;
  5. Blue; Green; White; Orange;
  6. Orange
  7. Green; White; Orange;
  8. White; Orange
  9. Green;

I used this code line to do that:

lines = i.split(";")[2]

The problem is that some of the lines have only one column or two, so it gives me 'index out of range' error. Please tell me how to go about this problem?

thanks a lot Adia

+1  A: 

what about something like this:

cols = i.split(";")
if (len(cols) >= 3):
    lines = cols[2]
else:
    #whatever you want here
Mike Clark
+1  A: 

use a slice instead of an index.

>>> with open('test.txt') as f_in:
...     column3 = (line.split(';')[2:3] for line in f_in)
...     column3 = [item[0] for item in column3 if item]
... 
>>> column3
[' Green', ' Orange', ' White', ' Green', ' White', ' Orange']
aaronasterling
+1: Had pretty much the same idea in mind.
eldarerathis
A: 

What about doing

for line in open("foo"):
    items = line.split(";")
    if len( items ) > 2:
        #do what you want to do

If you want access to all the items in any column with a default value applied:

izip_longest( *(line.split(";") for line in file("foo")), fillvalue = None )

using izip_longest from itertools will give you an iterator of tuples which have the value None in the places where a value is missing. Or you could use "" for an empty string. Here's what you'd get out if you iterated through the entire example using izip_longest:

(Red, Green, Blue, Red, Blue, Orage, Green, White, Green)
(Blue, White, Green, Blue, Green, None, White, Orage, None)
(Green, Oranage, White, Green, White, None, Orange, None, None)
(White, None, None, White, Orange, None, None, None, None)
(Orange, None, None, None, None, None, None, None, None, None)
wheaties
@SilentGhost: `file` is an alias for `open` in Python 2, albeit not common and generally not recommended.
delnan
@delnan: no it isn't. docs clearly say it's preferable to use `open` and not invoke constructor directly.
SilentGhost
@SilentGhost changed it to open.
wheaties
@SilentGhost: Um, that's what I said. (Okay, I edited a few seconds later - but I only clarified, I never wrote `file` is preferred).
delnan
+1  A: 

The simple solution is to check the number of columns and ignore lines with less than three columns.

third_columns = []
with open("...") as infile:
    for line in infile:
        columns = line.split(';')
        if len(columns) >= 3:
            third_columns.append(columns[2])

And if you parse CSV (seems like you do), you better use one of the numerous existing CSV parsers, e.g. the one in the standard library.

delnan
A: 
for line in open("file"):
    try:
        s=line.split(";")[2]
    except: pass
    else:
        print s
ghostdog74
bare excepts are evil
SilentGhost