Python'daki CSV, Windows'ta ekstra bir satır başı ekliyor


231
import csv
outfile = file('test.csv', 'w')
writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
writer.writerow(['hi','dude'])
writer.writerow(['hi2','dude2'])
outfile.close()

Her satırda test.csvfazladan bir dosya oluşturur \r, şöyle:

test.csv

hi,dude\r\r\nhi2,dude2\r\r\n

beklenen yerine:

hi,dude\r\nhi2,dude2\r\n

Bu neden oluyor ya da bu aslında istenen davranış mı?

Not:

  • Bu davranış, Python 2 veya 3 ile oluşabilir.

Yanıtlar:


311

Python 3:

with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    ...
  • Tarafından açıklamalarda belirtildiği gibi CoDEmanX , setnewline='\n'
with open('output.csv', 'w', newline='\n', encoding='utf-8') as f:
    writer = csv.writer(f)
    ...

Python 2:

Windows'ta, her zaman ikili modda (dosyalarınızı açmak "rb"veya "wb"onları geçirmeden önce,) csv.readerya csv.writer.

Dosya bir metin dosyası olmasına rağmen, CSV, kayıtları ayıran ilgili kütüphaneler tarafından ikili bir biçim olarak kabul edilir \r\n. Bu ayırıcı metin modunda yazıldıysa, Python çalışma zamanı değiştirir \nile \r\ndolayısıyla \r\r\ndosyada gözlemledik.

Bu önceki cevaba bakınız .


3
Bu ASCII için iyidir, ancak UTF-8 gibi kodlamayı öldürür. Aşağıdaki Jason'ın çözümü benim için çalıştı.
Tom

66
Python 3, ben dosya nesnesi için aşağıdaki seçenekleri kullanarak düzeltmek başardı: open(..., "w", newline="\n", encoding="utf-8"). newlineboş bir dize, aynı sonuç olabilir. "wb"Python 3'te çalışmazsa, dizeler ve arabellek arabirimi uyumsuzdur.
CodeManX

Ekstra araba dönüşünü ele almanın zarif yolu
ForeverLearner

2
Python2'de çalışmaz, bu nedenle hem 2 hem de 3 ile uyumlu olmanız gerekiyorsa, @ jason-r-coombs tarafından verilen yanıtı kullanın:writer = csv.writer(f, lineterminator='\n')
yossiz74

4
Bu, böyle basit, ortak ve basit bir API'nin gerektiği gibi çalışmadığı için gerçek bir utanç
SomethingSomething

248

İken @ john-makineler iyi cevap verir, her zaman en iyi yaklaşım değil. Örneğin, tüm girişlerinizi CSV yazıcısına kodlamadığınız sürece Python 3'te çalışmaz. Ayrıca, komut dosyası akış olarak sys.stdout kullanmak istiyorsa bu sorunu gidermez.

Bunun yerine yazarı oluştururken 'lineterminator' niteliğini ayarlamanızı öneririm:

import csv
import sys

doc = csv.writer(sys.stdout, lineterminator='\n')
doc.writerow('abc')
doc.writerow(range(3))

Bu örnek Python 2 ve Python 3 üzerinde çalışacak ve istenmeyen yeni satır karakterlerini üretmeyecektir. Bununla birlikte, istenmeyen satırlar üretebileceğini unutmayın (Unix işletim sistemlerinde LF karakterini atlamak).

Bununla birlikte, çoğu durumda, davranışın tüm CSV'yi ikili bir format olarak işlemekten daha tercih edilebilir ve daha doğal olduğuna inanıyorum. Bu cevabı değerlendirmeniz için bir alternatif olarak sunuyorum.


6
Bence en iyi cevap bu. Unix'te sorunlu gelince, sys.platform'u çağırmaya ve dinamik olarak uğraşmaya ne dersiniz?
sovemp

4
Bence en iyi cevap ve lineterminator = '\ n' güzel çalışıyor.
eikonal

1
"Tüm girişlerinizi CSV yazarına kodlamazsanız" ortaya çıkan soruna bir örnek verebilir misiniz?
Stephen

DİKKAT: bu araçların kullanılması \rartık kaçmaz! Bu bir hata gibi görünüyor csvwriter, ama durduğu gibi, uyumsuz CSV çıktısı bu gitmek için yol olmadığı anlamına gelir .
flow2k

^MKabul edilen yanıtın 2 önerisi işe yaramazken bu benim için sorunu çözdü .
user985366

55

Python 3'te (Bunu Python 2'de denemedim), ayrıca

with open('output.csv','w',newline='') as f:
    writer=csv.writer(f)
    writer.writerow(mystuff)
    ...

uygun olarak belgeleri .

Daha ayrıntılı bilgi için dokümanın dipnotunda :

Newline = '' belirtilmezse, alıntılanan alanlara gömülü yeni satırlar doğru şekilde yorumlanmaz ve yazmada \ r \ n bağlantı kullanan platformlarda fazladan bir \ r eklenir. Csv modülü kendi (evrensel) satırsonu işlemeyi gerçekleştirdiğinden, yeni satır = '' belirtmek her zaman güvenli olmalıdır.


2
@ Yibo-Yang, Bana çok zaman kazandın.
1man

4
HARİKA. Python 3.5
jef

Neden bu varsayılan davranış olmasın?
Marc Stober

6

Sen tanıtabilirsiniz = '\ n' lineterminator csv yazar komuta parametresi.

import csv
delimiter='\t'
with open('tmp.csv', '+w', encoding='utf-8') as stream:
    writer = csv.writer(stream, delimiter=delimiter, quoting=csv.QUOTE_NONE, quotechar='',  lineterminator='\n')
    writer.writerow(['A1' , 'B1', 'C1'])
    writer.writerow(['A2' , 'B2', 'C2'])
    writer.writerow(['A3' , 'B3', 'C3'])

1
Python 3.5.2 ile, benim için işe yarayan tek şey buydu (sadece kullandım lineterminator='\n'); CSV modülünün kaynağı gibi görünüyordu \r\n. openHerhangi bir etki yaratacak argüman kümesi yok .
Tommy


3

Aşağıdaki gibi bir işlevi açmak için newline = "\ n" niteliğini eklemelisiniz:

with open('file.csv','w',newline="\n") as out:
    csv_out = csv.writer(out, delimiter =';')

2

DictWriter kullanıyorsanız, open işlevinden yeni bir satır ve writerow işlevinden yeni bir satırınız olacağını unutmayın. Fazladan yeni satırı kaldırmak için openline içinde newline = '' kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.