2016-02-19 36 views
3

當我將這個字符串寫入StringIO的格式更改時,該怎麼辦?使用csv.writer向StringIO寫入字符串,爲什麼會添加額外的字符?

header = '\r\n'.join(
    [unicode(line,'utf8') for line in 
    ['"Text"', 
    '"More Text"', 
    '',]]) 
print header 

輸出:

"Text" 
"More Text" 

而現在將它添加到我的StringIO的:

si = StringIO.StringIO() 

writer = csv.writer(si) 
writer.writerow(header)) 

si.getvalue() 

輸出:

'"""",T,e,x,t,"""","\r","\n","""",M,o,r,e, ,T,e,x,t,"""","\r","\n"\r\n' 

爲什麼加逗號和額外"字符?

+0

這是因爲頭已經是一個字符串,然後你遍歷的那個人物,所以只是直接刪除for循環和寫頭文件 – SirParselot

+0

@SirParselot我看到,我的非StringIO代碼工作的原因是因爲它正在使用新行寫入所有字符,但是一旦我寫入.csv,新行就全部消失。我正在編輯我的問題,我的新問題... – steven

+0

不,我的意思是'在標題循環中的行。 'header'是一個如此循環的字符串,它會給你每個字符,所以'line'實際上是一個字符。 – SirParselot

回答

2

這是因爲writer.addrow期望包含元素和字符串的iterable也是可迭代的。

I.e.驗證碼:

l = [1,2,3] 
for i in l: 
    print i 

會打印:

1 
2 
3 

原則同樣適用於字符串:

s = 'abc' 
for c in s: 
    print c 

會打印:

a 
b 
c 

最後,

writer.writerow([1,2,3]) # Gives you 1,2,3 
writer.writerow('abc')  # Gives you a,b,c 

由於header是您的示例中的字符串,因此其中的每個字符都被視爲單獨的行。然而,這導致了正確的行:

writer.writerow(['abc']) # Gives you abc 

最後,許多CSV方言使用引號當一些元素在他們的分隔符,因爲它位於引號內,即在這裏第一個逗號不被視爲分隔符:

writer.writerow(['a,b',3]) # Gives you "a,b",3 

當引用字符本身出現在元素中時,它也必須被轉義,所以它不會混淆解析器。如果啓用Dialect.doublequote標誌,CSV作家只會加倍:

writer.writerow(['a",b',3]) # "a"",b",3 
+1

你知道它爲什麼會加倍報價嗎? – SirParselot

+1

@SirParselot:許多CSV方言對帶空格的元素使用引號,即:「1 2」,3,「3 4 5」'。所以加倍他們是一種方法來逃避已引用轉義的字符串中的引號字符。它在文檔中提到:https://docs.python.org/2/library/csv.html#csv.Dialect.doublequote – myaut

+0

啊,這是有道理的。由於沒有空格,我沒有理解。 – SirParselot

相關問題