0

I would like to do a similar process to a csv file as detailed in this question, but I get an error message saying:

TypeError: list indices must be integers 

The csv file that I want to rearrange has a combination of float, text, and integer data types. I'm assuming this is the problem, but can't figure out a way to modify the code below to insert the data. It writes the header information in the new CSV file though.

I'm using the same code as suggested by John Machin, but my write names variable uses:

writenames = "ID,average,max,min,median,mode,stddev,skewness,kurtosis".split(",")
reader = csv.reader(open("/home/usrs/chris/Summary.csv", "rb"))
writer = csv.writer(open("/home/usrs/chris/SummaryNEW.csv", "wb"))
readnames = reader.next()
names2indicies = dict((name,index) for index, name in enumerate(readnames))
writeindices = [names2string[name] for name in writenames]
reorderfunct = operator.itemgetter(writeindices)
writer.writerow(writenames)
for row in reader:
    writer.writerow(reorderfunct(row))
Community
  • 1
  • 1
Czed
  • 187
  • 1
  • 3
  • 9
  • 2
    post your code as well as your input; just don't refer to another post – Fredrik Pihl Sep 28 '11 at 13:20
  • 1
    It would help if you could: post your actual code, include the part of the error messaging indicating at what line the error occurred, and one or two lines of sample data that trigger the error. – larsks Sep 28 '11 at 13:21
  • 1
    I tend to use Python for practically all my scripting needs, but this is one of those cases where `awk` might be a better tool for the job (assuming all you need to do is reorder columns). – NPE Sep 28 '11 at 14:08
  • The error you got indicates that you're storing the fields in a list. Your `writenames` line suggests you're trying to key on names. You need to either use integers to index the list items, or change the list to a dict so you can index on names. Without seeing the code I can't be more detailed. – Tom Zych Sep 28 '11 at 14:09

1 Answers1

2

operator.itemgetter() is all you need:

inp=csv.reader(open(...))
outp=csv.writer(open(...))
map(outp.writerow,map(operator.itemgetter(x,y,z),inp))

Where x,y,z are the columns you want to re-order.

However, since the first row in Summary.csv is headers, then you might consider using DictReader and DictWriter:

writenames = "ID,average,max,min,median,mode,stddev,skewness,kurtosis".split(",")
reader = csv.DictReader(open("/home/usrs/chris/Summary.csv", "rb"))
writer = csv.DictWriter(open("/home/usrs/chris/SummaryNEW.csv", "wb"), \
    fieldnames=writenames)
reorderfunct = lambda r: dict([(col, r[col]) for col in writenames])
writer.writeheader()
for row in reader:
    writer.writerow(reorderfunct(row))
Austin Marshall
  • 2,991
  • 16
  • 14
  • Please don't use `map` to replace a loop; you're violating `zen[1]`. `map` is for transforming lists to other lists. – Fred Foo Sep 28 '11 at 14:12
  • 2
    @oxtopus: Thanks for the DictReader and DictWriter solution! Only problem now is that the writer.writeheader() doesn't work. Commenting that line out rearranges the csv, but obviously the output is left without headers. – Czed Sep 28 '11 at 14:58
  • 1
    AttributeError: DictWriter instance has no attribute 'writeheader' – Czed Sep 28 '11 at 15:03
  • 2
    DictWriter.writeheader() is new in 2.7, you could try: writer.writerow(dict(zip(writenames,writenames))) – Austin Marshall Sep 28 '11 at 15:06