Why do I get:

Traceback (most recent call last):
File "./2csvtbl.py", line 31, in <module>
print row[k], row[-k]
IndexError: list index out of range

after running this code:


#!/usr/bin/env python

import csv
import random
alpha = 'abcdefghijklmnopqrstuvwxyz'
e = range(0,99)
x = random.sample(alpha,14)
y = random.sample(e,14)

c = csv.writer(open("test2.csv", "wb"))
c.writerow([x])

cr = csv.reader(open("test2.csv","rb"))

for row in cr:
print row[1], row[1]

print "How many rows?"
l = input()

k = 1

while k < int(l):

c = csv.writer(open("test.csv", "wb"))
c.writerow([y])
cr = csv.reader(open("test.csv","rb"))

for row in cr:
k +=1
print row[k], row[-k]


print "done"

First, you need to use the CODE button to maintain indents when you paste your code (you also get code coloring and line numbers, also good things). With Python particularly indent matters. Here is what I think you meant:

#!/usr/bin/env python

import csv
import random
alpha = 'abcdefghijklmnopqrstuvwxyz'
e = range(0,99)
x = random.sample(alpha,14)
y = random.sample(e,14)

c = csv.writer(open("test2.csv", "wb"))
c.writerow([x])

cr = csv.reader(open("test2.csv","rb"))

for row in cr:
  print row[1], row[1]

print "How many rows?"
l = input()

k = 1

while k < int(l):
  c = csv.writer(open("test.csv", "wb"))
  c.writerow([y])
  cr = csv.reader(open("test.csv","rb"))

  for row in cr:
    k +=1
    print row[k], row[-k]

print "done" 

Second: You get that result because on line 31, the index is out of range (of course): Which in this case means that the length of the row is less than k.

I would also restructure the program so you don't have to keep opening the csv.reader over and over again; and you should close it after each open. I suspect that may be a root of your difficulty?

Edited 3 Years Ago by pyTony: fixed formating

Thank you griswolf.

my code now looks like

#!/usr/bin/env python

import csv
import random
alpha = 'abcdefghijklmnopqrstuvwxyz'
e = range(0,99)
x = random.sample(alpha,14)

c = csv.writer(open("test2.csv", "wb"))
dialect = csv.QUOTE_MINIMAL
c.writerow([x])

cr = csv.reader(open("test2.csv","rb"), delimiter=':', quoting=csv.QUOTE_NONE)

for row in cr:
        print ', '.join(row)

print "How many rows?"
l = input()

k = 0

while k < int(l):

        y = random.sample(e,14)
        c.writerow([y])

        cr = csv.reader(open("test2.csv","rb"), delimiter=':', quoting=csv.QUOTE_NONE)
        for row in cr:
                print ','.join(row)

        k += 1

print "done"

the output looks like

"['d', 'j', 'e', 't', 'l', 'y', 'h', 'm', 'z', 'k', 'x', 'a', 'b', 'p']"
"[21, 89, 64, 56, 91, 78, 29, 32, 69, 92, 75, 6, 28, 2]"
"[41, 61, 58, 45, 16, 98, 28, 83, 86, 70, 57, 47, 95, 14]"
"[87, 98, 67, 14, 38, 36, 52, 22, 46, 11, 41, 80, 96, 61]"
"[4, 15, 14, 71, 0, 96, 51, 86, 39, 83, 6, 5, 37, 44]"
"[63, 44, 56, 20, 22, 33, 77, 40, 95, 13, 27, 15, 21, 75]"
"[46, 6, 54, 80, 34, 43, 45, 94, 60, 47, 40, 81, 96, 51]"

is it possible to get rid of the quotes and brackets?

(complete change by edit from my original post)
Hmm. I would have though ', '.join(aRow) would do it, but apparently not. Interestingly, when I run your code I get this:

940% python phelp.py
How many rows?
9
done

In other words: No output.

I see you are using the builtin input() function. That is deprecated in Python 2.x. You should almost always use raw_input() which returns a string that must be converted to a number if you need a number. It is about robust code in the face of possibly malicious user input.

I'm going to just post this now and poke at the code a bit before I respond again.

Edited 5 Years Ago by griswolf: n/a

sure. You use the join method of strings so instead of calling print a_list , you might call print ', '.join(a_list)

i am already doing that but there are still commas

apparently my lack of output has to do with platform or something. You never close the open file from line 9, so on my OS, it doesn't flush, and the subsequent read gets nothing. If I modify lines 9,10,11 to this code, then I get output, but a failure on (my) line 31 (I/O operation on closed file):

with open('test2.csv','wb') as wr:
  c = csv.writer(wr)
  dialect = csv.QUOTE_MINIMAL
  c.writerow([x])

The join is doing nothing because the row is a list holding a single string, when seen by csv.reader() Replace line 16 with this: print "RAW: %r"%row to see it

Edited 5 Years Ago by griswolf: n/a

I changed my code to this

#!/usr/bin/env python

import csv
import random

alpha = 'abcdefghijklmnopqrstuvwxyz'
e = range(0,99)
x = random.sample(alpha,14)


with  open('test3.csv','wb') as wr:
    c = csv.writer(wr)
    dialect = csv.QUOTE_MINIMAL
    c.writerow([x])

cr = csv.reader(open("test2.csv","rb"))

for row in cr:
    print ', '.join(row)

print "How many rows?"
l = raw_input()

k = 1

while k < int(l):

    with open('test3.csv','wb') as wr:
        c = csv.writer(wr)
        dialect = csv.QUOTE_MINIMAL
        c.writerow([x])

    cr = csv.reader(open("test2.csv","rb"))

    for row in cr:
        print ','.join(row)

    k += 1

print "done"

and now my output is no longer printed in a csv file and when I make l=6 I get the six lines I want six times.

Your loop at line 26 opens and closes the csv reader and writer "l" times, a considerable waste of effort. And in each pass through the loop, at line 35 and 36, you print every line that is (so far) in the csv file: Probably not what you want.

I think that what you really want (not sure) is code like this:

number = readNumberOfLinesFromUser()
writeRandomLines(number)
readLinesFromFileAndPrintThem()

Of course I've written function calls, but these are simple things, and not really re-used so you can just write them in line (as you have done) instead.

This question has already been answered. Start a new discussion instead.