पायथन के साथ लिखी गई CSV फ़ाइल में प्रत्येक पंक्ति के बीच खाली लाइनें हैं


446
import csv

with open('thefile.csv', 'rb') as f:
  data = list(csv.reader(f))
  import collections
  counter = collections.defaultdict(int)

  for row in data:
        counter[row[10]] += 1


with open('/pythonwork/thefile_subset11.csv', 'w') as outfile:
    writer = csv.writer(outfile)
    for row in data:
        if counter[row[10]] >= 504:
           writer.writerow(row)

यह कोड पढ़ता है thefile.csv, परिवर्तन करता है और परिणामों को लिखता है thefile_subset1

हालाँकि, जब मैं माइक्रोसॉफ्ट एक्सेल में परिणामी सीएसवी खोलता हूं, तो प्रत्येक रिकॉर्ड के बाद एक अतिरिक्त रिक्त रेखा होती है!

क्या इसे बनाने के लिए एक अतिरिक्त खाली लाइन नहीं है?


4
कृपया पुष्टि करें कि ऐसा तब होता है जब आप उस कोड को विंडोज
जॉन मैकिन


इस सूत्र पर उत्तर देखें: stackoverflow.com/questions/3348460/…
Febin मैथ्यू

जवाबों:


887

पायथन 2 में, के बजाय outfileमोड के साथ खोलें । लिखते हैं सीधे फाइल में। यदि आप फ़ाइल को बाइनरी मोड में नहीं खोलते हैं , तो यह लिख देगा क्योंकि विंडोज टेक्स्ट मोड प्रत्येक में अनुवाद करेगा ।'wb''w'csv.writer\r\n\r\r\n\n\r\n

पायथन 3 में आवश्यक सिंटैक्स बदल गया (नीचे दिए गए दस्तावेज़ीकरण लिंक देखें), इसलिए इसके बजाय outfileअतिरिक्त पैरामीटर newline=''(खाली स्ट्रिंग) के साथ खोलें ।

उदाहरण:

# Python 2
with open('/pythonwork/thefile_subset11.csv', 'wb') as outfile:
    writer = csv.writer(outfile)

# Python 3
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
    writer = csv.writer(outfile)

प्रलेखन लिंक


1
वैसे भी @Mark Tolonen के जवाब ने अतिरिक्त फ़ाइल (मानक) से जुड़े कई सवालों को हल किया जब एक मानक (कोई सीएसवी का उपयोग नहीं किया गया) पाठ फ़ाइल को सहेजा गया।
dlewin

1
2.6 / 2.7 और 3 के बीच संगतता के लिए, आप तर्क के io.openसाथ उपयोग कर सकते हैं newlines। यदि आप अभी भी 2.x में लिख रहे हैं, तो यह एक बेहतर विकल्प की तरह लगता है क्योंकि यह आगे संगत है।
jpmc26

@ jpmc26 आम तौर पर यह अच्छी सलाह है, लेकिन सीएसवी मॉड्यूल ठीक से काम नहीं करता है io.openunicodecsvपायथन 2.7 के लिए एक 3 पार्टी मॉड्यूल है जो बेहतर काम करता है।
मार्क तोलोन

किसी भी विचार क्यों newline=''StringIO या TemporaryFile के साथ चाल python3 में काम नहीं करता है?
fmoo

@fmoo परिभाषित करता है "काम नहीं करता है"। वे दोनों वे काम करते हैं जो मुझे उम्मीद है। StringIOबफ़र समान कोड बिंदु है जो किसी फ़ाइल में एन्कोड किया जाएगा, और पैरामीटर TemporaryFileका समर्थन करता है newline, इसलिए इसे उसी तरह खोला जा सकता है open। एक नमूना कार्यक्रम के साथ एक प्रश्न पूछें जो काम नहीं कर रहा है।
मार्क टॉलेनन

65

फ़ाइल को बाइनरी मोड "wb" में खोलना पायथन 3+ में काम नहीं करेगा। या इसके बजाय, आपको अपने डेटा को लिखने से पहले बाइनरी में बदलना होगा। यह सिर्फ एक परेशानी है।

इसके बजाय, आपको इसे टेक्स्ट मोड में रखना चाहिए, लेकिन न्यूलाइन को खाली के रूप में ओवरराइड करें। इस तरह:

with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:

13

सरल उत्तर यह है कि सीएसवी फाइलें हमेशा बाइनरी मोड में खोली जानी चाहिए चाहे इनपुट या आउटपुट के लिए, अन्यथा विंडोज पर लाइन समाप्त होने की समस्याएं हैं। विशेष रूप से उत्पादन पर सीएसवी मॉड्यूल लिखेंगे \r\n(मानक CSV पंक्ति टर्मिनेटर) और फिर (पाठ मोड में) क्रम बदल देगा \nद्वारा \r\n(विंडोज मानक लाइन टर्मिनेटर) का एक परिणाम दे रही है \r\r\n

साथ नगण्य lineterminatorसमाधान नहीं है।


यह CSV "मानक" क्या है जिसके बारे में आप बोलते हैं?
डैन ब्रेसलाउ

3
@ दान: मैंने विशेषण के रूप में "मानक" का इस्तेमाल किया, संज्ञा का नहीं, जिसका अर्थ "सामान्य" या "सामान्य" होता है। यदि आप एक (संज्ञा) मानक के लिए एक सन्निकटन चाहते हैं, तो tools.ietf.org/html/rfc4180
John Machin

1
बिंदु (जैसा कि आप का अर्थ है) कि कोई मानक नहीं है। वह RFE सूचनात्मक है। जबकि \ r \ n विंडोज पर "मानक" हो सकता है, मुझे यकीन है कि यूनिक्स एप्लिकेशन आमतौर पर इसे इस तरह से नहीं देखते हैं।
डैन ब्रेस्लाउ

2
@ दान: यह सही है - कोई मानक नहीं है। लिपियों को लिनेटेरिमिनेटर निर्दिष्ट करना चाहिए [जिसे रोटरमिनेटर नाम दिया जाना चाहिए] वे चाहते हैं (यदि डिफ़ॉल्ट नहीं है) और अभी भी बाइनरी मोड का उपयोग करें यदि स्क्रिप्ट विंडोज पर चल रही है तो अन्यथा "लाइनमेटेरिनेटर" को भरपाई की जा सकती है।
जॉन माकिन

8

नोट: ऐसा लगता है कि यह पसंदीदा समाधान नहीं है क्योंकि विंडोज सिस्टम पर अतिरिक्त लाइन कैसे जोड़ी जा रही थी। अजगर दस्तावेज़ में कहा गया है :

यदि csvfile एक फ़ाइल ऑब्जेक्ट है, तो इसे उन प्लेटफ़ॉर्म पर 'b' फ़्लैग के साथ खोला जाना चाहिए जहाँ इससे फ़र्क पड़ता है।

विंडोज एक ऐसा प्लेटफॉर्म है, जहां फर्क पड़ता है। लाइन टर्मिनेटर को बदलते समय जैसा कि मैंने नीचे वर्णित समस्या को ठीक किया है, फ़ाइल को बाइनरी मोड में खोलकर समस्या को पूरी तरह से टाला जा सकता है। कोई कह सकता है कि यह समाधान अधिक "ग्यारह" है। लाइन टर्मिनेटर के साथ "फ़िडलिंग" के कारण इस मामले में सिस्टम के बीच का अनुपातहीन कोड हो सकता है, जहां एक फाइल को बाइनरी मोड में यूनिक्स सिस्टम पर खोलने से कोई प्रभाव नहीं पड़ता है। अर्थात। इसका परिणाम क्रॉस सिस्टम संगत कोड है।

से अजगर डॉक्स :

विंडोज पर, मोड में संलग्न 'बी' फ़ाइल को बाइनरी मोड में खोलता है, इसलिए 'आरबी', 'डब्ल्यूबी' और 'आर + बी' जैसे मोड भी हैं। विंडोज पर पायथन पाठ और बाइनरी फ़ाइलों के बीच अंतर करता है; जब डेटा पढ़ा या लिखा जाता है तो टेक्स्ट फ़ाइलों में अंत-पंक्ति वर्ण स्वचालित रूप से थोड़े बदल जाते हैं। डेटा को फ़ाइल करने के लिए पर्दे के पीछे का यह संशोधन ASCII टेक्स्ट फ़ाइलों के लिए ठीक है, लेकिन यह JPEG या EXE फ़ाइलों की तरह ही द्विआधारी डेटा को भ्रष्ट कर देगा। ऐसी फ़ाइलों को पढ़ते और लिखते समय बाइनरी मोड का उपयोग करने के लिए बहुत सावधान रहें। यूनिक्स पर, यह मोड में एक 'बी' को जोड़ने के लिए चोट नहीं करता है, इसलिए आप इसे सभी बाइनरी फ़ाइलों के लिए प्लेटफ़ॉर्म-स्वतंत्र रूप से उपयोग कर सकते हैं।

मूल :

Csv.writer के लिए वैकल्पिक पैरामैटर्स के एक भाग के रूप में यदि आपको अतिरिक्त रिक्त लाइनें मिल रही हैं, तो आपको lineterminator ( यहां जानकारी ) को बदलना पड़ सकता है । नीचे दिए गए उदाहरण को पायथन पेज csv डॉक्स से लिया गया है। इसे जो कुछ भी होना चाहिए, उसे '\ n' से बदलें। के रूप में यह समस्या है या नहीं काम कर सकते हैं पर सिर्फ अंधेरे में एक छुरा है, लेकिन यह मेरा सबसे अच्छा अनुमान है।

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), lineterminator='\n')
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

मैं इस बारे में पोस्ट करने वाला था - lineterminator = '\ n' ने मेरे लिए एक साधारण परीक्षा में काम किया।
डैन ब्रेस्लाउ

क्या मैं ऐसा कर सकता हूँ ?? खुले ('/ pythonwork / thefile_subset11.csv', 'w') के साथ, lineterminator = '\ n' आउटफिट के रूप में:
l -'''''--------- '' '' '' '' '' ''

1
@I__: आपको वास्तव में पायथन डॉक्स का उपयोग शुरू करना चाहिए। डेरेक ने आपको लिंक दिया: docs.python.org/library/csv.html
Dan Breslau

5

मैं इस जवाब को लिख रहा हूँ अजगर 3, क्योंकि मैं शुरू में एक ही समस्या है।

मैं arduino का उपयोग करके डेटा प्राप्त करने वाला था PySerial, और उन्हें एक .csv फ़ाइल में लिखना था। मेरे मामले में प्रत्येक पढ़ने के साथ समाप्त हुआ '\r\n', इसलिए न्यूलाइन हमेशा प्रत्येक पंक्ति को अलग कर रहा था।

मेरे मामले में, newline=''विकल्प काम नहीं किया। क्योंकि इसमें कुछ त्रुटि दिखाई गई जैसे:

with open('op.csv', 'a',newline=' ') as csv_file:

ValueError: illegal newline value: ''

तो ऐसा लगता था कि वे यहाँ पर नईलाइन की चूक को स्वीकार नहीं करते हैं।

केवल यहाँ एक उत्तर को देखकर, मैंने लेखक वस्तु में लाइन टर्मिनेटर का उल्लेख किया, जैसे,

writer = csv.writer(csv_file, delimiter=' ',lineterminator='\r')

और यह मेरे लिए अतिरिक्त newlines लंघन के लिए काम किया।


2
यह गलत है। with open('my_file.csv', 'a',newline='') as csvfile: बिल्कुल ठीक काम करता है। आपके उत्तर के साथ समस्या यह है कि यहाँ आप के ' 'बजाय लिख रहे हैं''
Nasrin

2
with open(destPath+'\\'+csvXML, 'a+') as csvFile:
    writer = csv.writer(csvFile, delimiter=';', lineterminator='\r')
    writer.writerows(xmlList)

"लाइनमेटर्मिनेटर = '\ r'" दो के बीच खाली पंक्ति के बिना, अगली पंक्ति में जाने की अनुमति देता है।


1

इस उत्तर से उधार लेना , ऐसा लगता है कि सबसे साफ समाधान का उपयोग करना है io.TextIOWrapper। मैं इस समस्या को अपने लिए हल करने में कामयाब रहा:

from io import TextIOWrapper

...

with open(filename, 'wb') as csvfile, TextIOWrapper(csvfile, encoding='utf-8', newline='') as wrapper:
    csvwriter = csv.writer(wrapper)
    for data_row in data:
        csvwriter.writerow(data_row)

उपरोक्त उत्तर पाइथन 2 के साथ संगत नहीं है। संगतता के लिए, मुझे लगता है कि एक ifब्लॉक में सभी लेखन तर्क को लपेटने की आवश्यकता होगी :

if sys.version_info < (3,):
    # Python 2 way of handling CSVs
else:
    # The above logic

0

CSV फ़ाइल में डेटा लिखने के लिए नीचे दी गई विधि का उपयोग करें।

open('outputFile.csv', 'a',newline='')

बस विधि के newline=''अंदर एक अतिरिक्त पैरामीटर जोड़ें open:

def writePhoneSpecsToCSV():
    rowData=["field1", "field2"]
    with open('outputFile.csv', 'a',newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(rowData)

यह अतिरिक्त पंक्तियाँ बनाए बिना CSV पंक्तियाँ लिखेगा!


-1

पायथन 3 का उपयोग करते समय कोडेक्स मॉड्यूल का उपयोग करके खाली लाइनों से बचा जा सकता है । जैसा कि प्रलेखन में कहा गया है, फाइलें बाइनरी मोड में खोली जाती हैं, इसलिए न्यूलाइन क्वार्ग का कोई परिवर्तन आवश्यक नहीं है। मैं हाल ही में उसी मुद्दे पर चल रहा था और जो मेरे लिए काम कर रहा था:

with codecs.open( csv_file,  mode='w', encoding='utf-8') as out_csv:
     csv_out_file = csv.DictWriter(out_csv)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.