2009-12-11 14 views
27

का उपयोग कर उदाहरण के लिए स्तंभ क्रम रखने के लिए क्या यह संभव है, मेरे csv के रूप में नीचे स्तंभ हैं:अजगर सीएसवी DictReader

आईडी, आईडी 2, दिनांक, नौकरी नहीं है, कोड

मैं की जरूरत है कॉलम को उसी क्रम में वापस लिखने के लिए। निर्देश तुरंत आदेश को झुकाता है, इसलिए मेरा मानना ​​है कि यह पाठक के साथ एक समस्या है।

उत्तर

42

पायथन का dict एस 3.6 से पहले आदेश बनाए रखता है।

हालांकि, यह है कि आप प्रयोग कर रहे हैं (के बाद आप पहली पंक्ति पढ़ा है! -) csv.DictReader के कहने करता स्ट्रिंग की एक .fieldnames सूची है, जो क्रम में है।

तो,

for rowdict in myReader: 
    print ['%s:%s' % (f, rowdict[f]) for f in myReader.fieldnames] 

तुम्हें दिखाता है कि आदेश वास्तव में बनाए रखा है (बेशक .fieldnames में, कभीdict में - कि अजगर में आंतरिक रूप से असंभव है -!)।

तो, मान लें कि आप a.csv पढ़ना चाहते हैं और उसी कॉलम ऑर्डर के साथ b.csv लिखना चाहते हैं। सादा पाठक और लेखक का उपयोग करना बहुत आसान है, इसलिए आप इसके बजाय डिक्ट किस्मों का उपयोग करना चाहते हैं ;-)। यह मानते हुए कि आप a.csv में हेडर है (otherewise आप उस पर एक DictReader उपयोग नहीं कर सकते) और b.csv में सिर्फ एक ही हेडर चाहते

import csv 

a = open('a.csv', 'r') 
b = open('b.csv', 'w') 
ra = csv.DictReader(a) 
wb = csv.DictWriter(b, None) 

for d in ra: 

    if wb.fieldnames is None: 
    # initialize and write b's headers 
    dh = dict((h, h) for h in ra.fieldnames) 
    wb.fieldnames = ra.fieldnames 
    wb.writerow(dh) 

    wb.writerow(d) 

b.close() 
a.close() 

: ठीक है, एक ही रास्ता है ...।

+0

धन्यवाद एलेक्स मार्टेलि! आप यहां कर्तव्य की कॉल के ऊपर और ऊपर चले गए हैं :) और ... इसकी सराहना की जाती है! मुझे एहसास नहीं हुआ कि फील्डनाम थे, लेकिन एपीआई दस्तावेज़ों को दोबारा पढ़ना मैं अब इसे देख सकता हूं। विकल्प के लिए धन्यवाद, लेकिन चूंकि मेरा डिक्ट्रेडर अब अच्छी तरह से काम कर रहा है, इसलिए मैं इसके साथ रहूंगा। – Alex

+0

@RaffiKhatchadourian a a.csv है, b है b.csv ra संभवतया फ़ाइल ए से पढ़ने के लिए खड़ा है, संभवतया फ़ाइल बी, डी के लिए डी, शब्दकोश के लिए डीएच, शब्दकोश हेडर के लिए डीएच .... एलेक्स भयानक स्पष्टीकरण के लिए धन्यवाद ! – Deep

+0

किसी भी कारण से आप पूरे 'dh = dict (...' '... wb.writerow (dh) 'के माध्यम से गए थे, जब आप' wb.fieldnames = ra.fieldnames; wb.writeheader()' कर सकते थे? – Baldrickk

7
from csv import DictReader, DictWriter 

with open("input.csv", 'r') as input_file: 
    reader = DictReader(f=input_file) 
    with open("output.csv", 'w') as output_file: 
     writer = DictWriter(f=output_file, fieldnames=reader.fieldnames) 
     for row in reader: 
      writer.writerow(row) 
2

मैं जानता हूँ कि इस सवाल पुराना है ... लेकिन अगर आप DictReader उपयोग करते हैं, आप इसे fieldnames परम

1

को fieldnames डिफ़ॉल्ट DictReader ओवरराइड करने के लिए अनुमति नहीं है दुर्भाग्यवश के साथ एक आदेश दिया सूची पारित कर सकते हैं dict वर्ग, एक कस्टम DictReader चाल करना होगा, हालांकि

import csv 

class DictReader(csv.DictReader): 
    def __init__(self, *args, **kwargs): 
     self.dict_class = kwargs.pop(dict_class, dict) 
     super(DictReader, self).__init__(*args, **kwargs) 

    def __next__(self): 
     ''' copied from python source ''' 
     if self.line_num == 0: 
      # Used only for its side effect. 
      self.fieldnames 
     row = next(self.reader) 
     self.line_num = self.reader.line_num 

     # unlike the basic reader, we prefer not to return blanks, 
     # because we will typically wind up with a dict full of None 
     # values 
     while row == []: 
      row = next(self.reader) 
     # using the customized dict_class 
     d = self.dict_class(zip(self.fieldnames, row)) 
     lf = len(self.fieldnames) 
     lr = len(row) 
     if lf < lr: 
      d[self.restkey] = row[lf:] 
     elif lf > lr: 
      for key in self.fieldnames[lr:]: 
       d[key] = self.restval 
     return d 

यह इतना

import collections 

csv_reader = DictReader(f, dict_class=collections.OrderedDict) 
# ... 
की तरह उपयोग
3

प्रत्येक पंक्ति dictDictReader.fieldnames द्वारा क्रमबद्ध OrderedDict बनाएं।

import csv 
from collections import OrderedDict 

reader = csv.DictReader(open("file.csv")) 
for row in reader: 
    sorted_row = OrderedDict(sorted(row.items(), 
      key=lambda item: reader.fieldnames.index(item[0]))) 
संबंधित मुद्दे