0

I have a list like this.

all_chords = [['C', 'C', 'E', 'G'],
 ['CM7', 'C', 'E', 'G', 'B'],
 ['C7', 'C', 'E', 'G', 'Bb'],
 ['Cm7', 'C', 'Eb', 'G', 'Bb'],
 ['Cm7b5', 'C', 'Eb', 'Gb', 'Bb'],
 ['Cdim7', 'C', 'Eb', 'Gb', 'Bbb(A)'],
 ['Caug7', 'C', 'E', 'G#', 'Bb'],
 ['C6', 'C', 'E', 'G', 'A'],
 ['Cm6', 'C', 'Eb', 'G', 'A'],
]

I want to print out to a csv file, something like this.

C_chords.csv

C;C,E,G
CM7;C,E,G,B
C7;C,E,G,Bb
Cm7;C,Eb,G,Bb
Cm7b5;C,Eb,Gb,Bb
Cdim7;C,Eb,Gb,Bbb(A)
Caug7;C,E,G#,Bb
C6;C,E,G,A
Cm6;C,Eb,G,A

It has two fileds which are separted by semicolon. (not by a comma)

I used csv module, like this.

myfile = open('C_chords.csv','w')
wr = csv.writer(myfile, quotechar=None)
wr.writerows(all_chords)
myfile.close()

The result is..

C,C,E,G
CM7,C,E,G,B
C7,C,E,G,Bb
Cm7,C,Eb,G,Bb
Cm7b5,C,Eb,Gb,Bb
Cdim7,C,Eb,Gb,Bbb(A)
Caug7,C,E,G#,Bb
C6,C,E,G,A
Cm6,C,Eb,G,A

Should I modify the list? Somewhat like this? [['C',';', 'C', 'E', 'G'],.......]

or any other brilliant ideas do you guys have?

Thanks in advance.

3
  • I don't believe it is a CSV file that you are trying to write. All values should be coma-separated values, or at list character-separated values. You should use two different characters for a csv file. So, you should do it without the csv module as erlc mentioned it Commented Jul 31, 2013 at 9:41
  • @Paco; I do not understand what you meant. "You should use two different characters for a csv file." Two different characters??? Commented Jul 31, 2013 at 10:42
  • I mean "shouldn't", sorry. You are using ';' and ',' as values to separates data Commented Jul 31, 2013 at 10:43

2 Answers 2

2

You're writing four columns, not two, if you want the last list elements be one single column, you need to join them first manually.

And you need to change the delimiter if you want the csv semicolon separated, not the quote character:

import csv

all_chords = [['C', 'C', 'E', 'G'],
 ['CM7', 'C', 'E', 'G', 'B'],
 ['C7', 'C', 'E', 'G', 'Bb'],
 ['Cm7', 'C', 'Eb', 'G', 'Bb'],
 ['Cm7b5', 'C', 'Eb', 'Gb', 'Bb'],
 ['Cdim7', 'C', 'Eb', 'Gb', 'Bbb(A)'],
 ['Caug7', 'C', 'E', 'G#', 'Bb'],
 ['C6', 'C', 'E', 'G', 'A'],
 ['Cm6', 'C', 'Eb', 'G', 'A'],
]

myfile = open('C_chords.csv','w')
wr = csv.writer(myfile, delimiter=';')
wr.writerows([c[0], ','.join(c[1:])] for c in all_chords)
myfile.close()
Sign up to request clarification or add additional context in comments.

3 Comments

+1. The open must use the argument newline='' when working with csv module in Python 3.
@pepr; It works fine without newline='' for me on Ubuntu 13.04. Libreoffice can read the cvs file without any problem. Thanks anyway.
@nemonein: The problem is that newline can generally be a part of a field value. (It can happen that the bug only does not manifest in your case.) This way, the csv module needs to process the file content in a kind of binary mode (this was used in Python 2 implementation of csv). However, Python 3 strings are more strict than Python 2 strings. The items must be processed as Unicode strings and cannot contain whatever bytes that cannot be interpreted as Unicode characters. Another part of the problem is that there are other operating systems where newline is not just the LF character.
2

I think it's easier to do it without the csv module:

with open('C_chords.csv','w') as out_file:
  for row in all_chords:
    print('{};{}'.format(row[0], ','.join(row[1:])), file=out_file)

2 Comments

@nemonein: Later, you can use line.split(';', 1) to split the line it only at the first semicolon (i.e. one split at maximum) for the case when another semicolon is in the value part.
+1 as it gives you more freedom when formatting the result. I suggest to use out_file.write('{};{}\n'.format(...)) instead of print.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.