2009-12-11 16 views
27

を使用して列の順序を維持することができる、私のcsvファイルは以下のように列を持っている:私は必要は、それが例えばPythonのcsvファイルDictReader

ID、ID2、日付、ジョブ番号、コード

列を同じ順序で書き戻します。ディクテーションはすぐに注文を混乱させるので、読者にはもっと問題があると思います。

答えて

42

Pythonのdict sが3.6より前の順序を維持しません。

はしかし、あなたは(あなたが最初の行を読んだ後! - )を使用しているcsv.DictReaderのインスタンスが順番に IS文字列の.fieldnamesリストを、持っていません。

ので、

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

は順序が実際に維持されていることを示します( - それはPythonで本質的に不可能だ - NEVERdictで、当然の.fieldnamesに!)。

だから、あなたがa.csvを読み、同じ列の順序でb.csvを書きたいとしよう。プレーンなリーダーとライターを使うのは簡単すぎるので、代わりにDictの品種を使いたいと思っています。まあ、一つの方法はある...:

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() 

(あなたがそれにDictReaderを使用することはできませんotherewise)とb.csvでちょうど同じヘッダをしたいあなたはa.csvのヘッダーを持っていると仮定します。

+0

おかげでアレックスマルテッリ!あなたはここで義務の呼び出しの上に行ってきました:)そして...それは感謝しています!私はfieldnamesがあることに気がつかなかったが、私は今すぐ見ることができるAPIのドキュメントを読んでいる。代わりのおかげで、私のDictReaderがうまくいきましたので、私はそれに固執します。 – Alex

+0

@RaffiKhatchadourian aはa.csvあり、bが.... b.csvは、おそらく、Bをファイルに書き込み、辞書用D、辞書ヘッダーのDHのため、おそらくWB、ファイルからの読み込みを意味し、RA素晴らしい説明のため アレックスのおかげであります! – Deep

+0

あなたは 'wb.fieldnames = ra.fieldnamesを行っている可能性ときに' '全体DH = dictの(...' '... wb.writerow(DH)を経て、なぜ何らかの理由; 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を使用する場合、デフォルトのDictReader Unfortunatley fieldnamesのparam

1

にフィールド名と順序付きリストを渡すことができますオーバーライドを許可しません。 dictのクラスは、カスタムDictReaderは、トリックを行うだろうけれどもそう

import collections 

csv_reader = DictReader(f, dict_class=collections.OrderedDict) 
# ... 
よう

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 

使用して

3

DictReader.fieldnamesでソート各行dictから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]))) 
関連する問題