2016-08-02 8 views
0

存在しない場合:のpythonのcsvライター行キーは、次のスクリプトを実行erroringさ

import csv,time,string,os,requests, datetime 

test = "\\\\network\\Shared\\test.csv" 

fields = ["id", "Expiration Date", "Cost", "Resale" ] 

with open(test) as infile, open("c:\\upload\\tested.csv", "wb") as outfile: 
    r = csv.DictReader(infile) 
    w = csv.DictWriter(outfile, fields, extrasaction="ignore") 
    r = (dict((k, v.strip()) for k, v in row.items() if v) for row in r) 

    wtr = csv.writer(outfile)                                                                                   
    wtr.writerow(["id", "upload_date", "cost", "resale"]) 
    for i, row in enumerate(r, start=1): 
     row['id'] = i 
     print(row['Expiration Date'] 
     row['Expiration Date'] = datetime.datetime.strptime(row['Expiration Date'][:10], "%m/%d/%Y").strftime("%Y-%m-%d") 
     w.writerow(row) 


D:\Python\Scripts>python test.py 
Traceback (most recent call last): 
    File "test.py", line 18, in <module> 
    print(row['Expiration Date']) 
KeyError: 'Expiration Date' 

だから、私は何が起こっているかを理解すると思います - 元のファイルから、このような何か:

Expiration Date  Cost  Resale 
2016-01-01   1.00  2.00 
        1.42  2.42 
2016-05-02   1.45  9.00 

を私が集めることができるものから、有効期限の列には行がありません。それが私のエラーの原因であると仮定して、DictWriterに余白をスキップさせるにはどうしたらいいですか?

答えて

1

は実際には、csv.DictReaderによって生成dictはちょうどそれが見つからないので、あなたがそのエラーを取得するべきではないフィールドにNoneを置きます。適切なdictを生成するために、DictReaderの機能を使用していません!私が知る限り、あなたは、r = (dict((k, v.strip()) for k, v in row.items() if v) for row in r)という行を使って自分自身を解析しようとします。しかし、それは実際には機能しません。あなたがその後の行を印刷する場合は、取得:

{'Expiration Date  Cost  Resale': '2016-01-01   1.00  2.00'} 
{'Expiration Date  Cost  Resale': '1.42  2.42'} 
{'Expiration Date  Cost  Resale': '2016-05-02   1.45  9.00'} 

だから、すべてのdictは、1つのキーだけが含まれています。ファイルの問題は、行間に有効な区切り文字がないことです。空白を使用するように見えますが、空白はExpiration Dateにもあります。あなたはそれを取り除かなければならないでしょう。あなたがそれを行う場合は、このようなDictReaderを使用することができます。

import csv,time,string,os,requests, datetime 

test = "test.csv" 

with open(test) as infile: 
    r = csv.DictReader(infile, delimiter=" ", skipinitialspace=True) 
for row in r: 
    print(row) 

今あなたを与えるだろう。

適切 dictある
{'Resale': '2.00', 'Cost': '1.00', 'ExpirationDate': '2016-01-01'} 
{'Resale': None, 'Cost': '2.42', 'ExpirationDate': '1.42'} 
{'Resale': '9.00', 'Cost': '1.45', 'ExpirationDate': '2016-05-02'} 

(読者は占いの方法がないことに注意してください、その最初の要素は欠落していますが)。今度は、完全ではない行を書き出しから除外するだけです。それを行うには良い方法はhereに記載されている:

import csv,time,string,os,requests, datetime 

test = "test.csv" 

with open(test) as infile: 
    r = csv.DictReader(infile, delimiter=" ", skipinitialspace=True) 

    for row in r: 
     if not any(val in (None, "") for val in row.itervalues()): 
      print(row) 

最後に、これはあなたのdict Sなど、すべての有効ライン与える:彼の中に読み、実際に

{'Resale': '2.00', 'Cost': '1.00', 'ExpirationDate': '2016-01-01'} 
{'Resale': '9.00', 'Cost': '1.45', 'ExpirationDate': '2016-05-02'} 
+0

私はr =(dict(k、v.strip())のk、vのrow.items()の場合はv)の行について実際には理解していませんでした 'line - コードそのものは私は、書かれる前に各値に空白をトリミングするようにしましたが、正しいと思います。この行を削除すると、この特定の問題が解決されますが、コードは空白を取り除いていました。 –

+0

@BrianPowellサンプルで使用した 'skipinitialspace = True'パラメータは、先行するすべての空白を取り除きます。それはあなたが必要とするものではありませんか? – jotasi

+0

私は、最初に空白がある、または最後に 'hello'という値をシートに入れました(これは50列のようですが、私がここで示したものではありません)。その空白が出ていますが、それは私の辞書を台無しにしてしまったと思います。私の理解では、 'skipinitialspace'は値の先頭から空白を削除するだけです。 –

0

x['Expiration Date']にあるdictにないものにアクセスするKeyErrorがあるので、代わりにx.get('Expiration Date')またはおそらく'Expiration Date' in xが存在し、条件付きでその行を破棄すると言うことができます。

+0

を欠陥があり、彼は何かを持っていることはありませんが、彼の 'dict'の' 'key ''としての' 'Expiration Date Cost Resale' 'を返します。 – jotasi

関連する問題