CSv.DictWriter দিয়ে কিভাবে শিরোনাম সারি লিখবেন?


114

ধরুন আমার একটি csv.DictReaderঅবজেক্ট আছে এবং আমি এটি CSV ফাইল হিসাবে লিখতে চাই। কিভাবে আমি এটি করতে পারব?

আমি জানি যে আমি এই জাতীয় ডেটার সারি লিখতে পারি :

dr = csv.DictReader(open(f), delimiter='\t')
# process my dr object
# ...
# write out object
output = csv.DictWriter(open(f2, 'w'), delimiter='\t')
for item in dr:
    output.writerow(item)

তবে আমি ক্ষেত্রের নামগুলি কীভাবে অন্তর্ভুক্ত করতে পারি?

উত্তর:


149

সম্পাদনা করুন:
2.7 / 3.2 এ একটি নতুন writeheader()পদ্ধতি রয়েছে । এছাড়াও, জন মাচিনের উত্তর শিরোনাম সারি লেখার একটি সহজ পদ্ধতি সরবরাহ করে। পদ্ধতিটি
ব্যবহারের সহজ উদাহরণ writeheader()এখন ২.7 / ৩.২ এ পাওয়া যায়:

from collections import OrderedDict
ordered_fieldnames = OrderedDict([('field1',None),('field2',None)])
with open(outfile,'wb') as fou:
    dw = csv.DictWriter(fou, delimiter='\t', fieldnames=ordered_fieldnames)
    dw.writeheader()
    # continue on to write data

ডিক্ট রাইটার ইনস্ট্যান্ট করাতে একটি ফিল্ড নেম যুক্তি প্রয়োজন। ডকুমেন্টেশন
থেকে :

ক্ষেত্রের নামগুলি প্যারামিটারটি ক্রমটি চিহ্নিত করে যেখানে অভিধানে লেখক () পদ্ধতিতে পাস করা মানগুলি csvfile এ লেখা হয়।

অন্য একটি উপায় রাখুন: ক্ষেত্রের নাম যুক্তিটি প্রয়োজনীয় কারণ পাইথন ডিক্টস সহজাতভাবে সীমান্তবিহীন।
নীচে আপনি একটি ফাইলে শিরোনাম এবং ডেটা কীভাবে লিখবেন তার একটি উদাহরণ রয়েছে।
দ্রষ্টব্য: withবিবৃতিটি ২.6-এ যুক্ত করা হয়েছিল। যদি 2.5 ব্যবহার করে:from __future__ import with_statement

with open(infile,'rb') as fin:
    dr = csv.DictReader(fin, delimiter='\t')

# dr.fieldnames contains values from first row of `f`.
with open(outfile,'wb') as fou:
    dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)
    headers = {} 
    for n in dw.fieldnames:
        headers[n] = n
    dw.writerow(headers)
    for row in dr:
        dw.writerow(row)

@ এফএম যেমন একটি মন্তব্যে উল্লেখ করেছে, আপনি এক-লাইনারে শিরোনাম-লেখাকে ঘনীভূত করতে পারেন, যেমন:

with open(outfile,'wb') as fou:
    dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)
    dw.writerow(dict((fn,fn) for fn in dr.fieldnames))
    for row in dr:
        dw.writerow(row)

12
+1 টি তবুও অন্য উপায় হেডার লিখতে: dw.writerow( dict((f,f) for f in dr.fieldnames) )
এফএমসি

2
@ অ্যাডাম: সংক্ষিপ্ত ওয়ান-লাইনারের জন্য, আমার উত্তর দেখুন।
জন মাচিন

2
@ জন: আপনার উত্তরটি +1; কেবলমাত্র "অন্তর্নিহিত লেখকের উদাহরণ" ব্যবহার করা অবশ্যই "শ্রমসাধ্য পরিচয়-ম্যাপিং" এর চেয়ে ভাল।
যান্ত্রিক_মেট

1
@ এন্ডোলিথ: প্রতিক্রিয়ার জন্য ধন্যবাদ অংশটি উত্তরের শীর্ষে সরানো হয়েছে।
যান্ত্রিক_মাট

1
যেহেতু আপনি একটি ডিক্রেডারও ব্যবহার করছেন তাই ক্ষেত্রগুলি যুক্ত করা সহজ dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)। এইভাবে, যদি আপনার ক্ষেত্রগুলি পরিবর্তিত হয় তবে আপনার ডিক্টরাইটার সামঞ্জস্য করার দরকার নেই।
স্পেনসার রথবুন

29

কয়েকটি বিকল্প:

(1) শ্রমসাধ্যভাবে আপনার ক্ষেত্রের নামগুলি থেকে একটি পরিচয়-ম্যাপিং (অর্থাত্ কিছুই করবেন না) তৈরি করুন যাতে CSV.DictWriter এটিকে আবার কোনও তালিকায় রূপান্তর করতে এবং csv.writer দৃষ্টান্তে এটি পাস করতে পারে।

(২) ডকুমেন্টেশনে "অন্তর্নিহিত writerউদাহরণ" উল্লেখ করা হয়েছে ... সুতরাং কেবল এটি ব্যবহার করুন (উদাহরণের শেষে)।

dw.writer.writerow(dw.fieldnames)

(3) সিএসভি এড়িয়ে চলুন। ডিকট্রাইটার ওভারহেড এবং csv.writer দিয়ে নিজেই করুন

তথ্য লেখার:

w.writerow([d[k] for k in fieldnames])

অথবা

w.writerow([d.get(k, restval) for k in fieldnames])

extrasaction"কার্যকারিতা" পরিবর্তে আমি নিজে কোডিং করতে পছন্দ করব; আপনি কেবল প্রথম অতিরিক্ত কী নয়, কী এবং মানগুলি দিয়ে সমস্ত "অতিরিক্ত" প্রতিবেদন করতে পারেন। ডিক্ট রাইটারের সাথে আসল উপদ্রবটি হ'ল হ'ল প্রতিটি ডিকটি নির্মিত হচ্ছিল বলে আপনি যদি নিজেই কীগুলি যাচাই করে থাকেন তবে আপনাকে অতিরিক্ততা = 'উপেক্ষা করুন' ব্যবহার করা মনে রাখতে হবে অন্যথায় এটি স্বল্প যাচ্ছে (ক্ষেত্রের নাম একটি তালিকা) চেকটি পুনরাবৃত্তি করুন:

wrong_fields = [k for k in rowdict if k not in self.fieldnames]

============

>>> f = open('csvtest.csv', 'wb')
>>> import csv
>>> fns = 'foo bar zot'.split()
>>> dw = csv.DictWriter(f, fns, restval='Huh?')
# dw.writefieldnames(fns) -- no such animal
>>> dw.writerow(fns) # no such luck, it can't imagine what to do with a list
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\python26\lib\csv.py", line 144, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "C:\python26\lib\csv.py", line 141, in _dict_to_list
    return [rowdict.get(key, self.restval) for key in self.fieldnames]
AttributeError: 'list' object has no attribute 'get'
>>> dir(dw)
['__doc__', '__init__', '__module__', '_dict_to_list', 'extrasaction', 'fieldnam
es', 'restval', 'writer', 'writerow', 'writerows']
# eureka
>>> dw.writer.writerow(dw.fieldnames)
>>> dw.writerow({'foo':'oof'})
>>> f.close()
>>> open('csvtest.csv', 'rb').read()
'foo,bar,zot\r\noof,Huh?,Huh?\r\n'
>>>

বর্তমানে পাইথন ৩.6- extrasactionতে কার্যকারিতা আরও কার্যকর হয়েছে বলে মনে হচ্ছে। এটি এখন wrong_fields = rowdict.keys() - self.fieldnames so it's effectively a নির্ধারিত `
মার্টিনিউ

আমি এই উত্তরটি 'ডিক্ট রাইটার এড়ানো' মন্তব্যের জন্য ভোটাভুটি করছি - এটি ব্যবহারে আমি কোনও সুবিধা দেখিনি, এবং আপনার ডেটা গঠন এবং csv.writer ব্যবহার করার জন্য আরও দ্রুত বলে মনে করি
neophytte

8

এটি করার আরেকটি উপায় হ'ল আপনার আউটপুটটিতে লাইনগুলি যুক্ত করার আগে যুক্ত করা, নিম্নলিখিত লাইন:

output.writerow(dict(zip(dr.fieldnames, dr.fieldnames)))

জিপ একই মানযুক্ত ডাবল্টের একটি তালিকা ফিরে আসবে। এই তালিকাটি অভিধানে শুরু করতে ব্যবহৃত হতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.