2016-05-17 38 views
1

私はcsvファイルを前処理しており、フィールドでフィルタリングされたcsvファイルデータで構成される3つの辞書を出力します。Python関数は一度だけ実行されます

セットアップである:

import csv 
from m_functions import region_goals  

csvFile = # a file path 

mnDict = dict() 
nlDict = dict() 
neDict = dict() 

# READ CSV 
weekList = csv.reader(open(csvFile)) 

# CREATE DICTIONARY FOR THIS WEEK AND REGION 
region_goals(weekList, "STR1", neDict) 
region_goals(weekList, "STR2", mnDict) 
region_goals(weekList, "STR3", nlDict) 

region_goals関数である:

def region_goals(csv, region, region_dictionary): 
    firstline = True 
    for row in csv: 
     if firstline: 
      firstline = False 
      continue 
     if row[14] == region: 
      if row[16] not in region_dictionary: 
       region_dictionary[row[16]] = float(row[6]) 
      else: 
       region_dictionary[row[16]] += float(row[6]) 
     else: 
      continue 
    return region_dictionary 

機能の最初の使用のために予想されるように出力が常にあります。 2回目の2回は関数を使用し、空の辞書が返されます。

私はこれが私には何か小さいものが欠けていると確信していますが、私はPythonには新しく、これをしばらく修正しようとしています。あなたの応答に事前に感謝します。

+0

最初の呼び出しですでにファイルを繰り返しているので、後続の呼び出しには何も読み込むことができません。 'weekList = csv.reader(open(csvFile))'への呼び出しを関数に移す(ファイルを再オープンする)か、csv.readerクラスがサポートしている場合は 'weekList.seek(0)'を試すことができますそれ。 –

+1

関数が3つのディクショナリを返す場合は、3回実行されます。 –

+0

ニースはArnabを試してみますが、上記を見れば、セットアップ中に3つの空の辞書が作成されます。 –

答えて

2

最初のパスの後、あなたはCSVファイルの最後にいるので、読むことが残っているので、再度開く必要があります。

また、オブジェクトをインプレース関数で変更するのは、最良の方法ではありません。毎回新しいオブジェクトを返すほうがよいでしょう。 g.d.d.cの提案当たり

import csv 
from m_functions import region_goals  

csvFile = # a file path 

regions = ['STR1', 'STR2', 'STR3'] 
for region in regions: 
    with csv.reader(open(csvFile)) as weekList: 
     region_dict = dict() 
     output = region_goals(weekList, region, region_dict) 
1

最初の関数呼び出しの後で既にファイルを読み込んだので、開いているファイルで'seek(0) 'を実行できます。 、

# READ CSV 
weekList = list(csv.reader(open(csvFile))) 

そして、あなたのコードは動作するはずです:

# READ CSV 
f = open(csvFile) 
weekList = csv.reader(f) 

region_goals(weekList, "STR1", neDict) 
f.seek(0) 
region_goals(weekList, "STR2", mnDict) 

EDIT: ファイルには大きすぎるおよび/またはあなたがより多くのメモリuseageを扱う場合は、あなたのような何かを行うことができなかった。このような何かを試してみてくださいただし、ファイル全体がメモリにロードされることに注意してください。

最も良い解決策は、これらの3つの辞書を1回のパスで取り込み、その関数を1回呼び出すことです。

+0

'f = open(csvFile)'であるべきでしょう。 – Achim

+0

'weekList.seek(0)'を意味しますか? –

+0

私はあなたがファイルを一度 'list'に読み込んでから、* list *を関数に渡す方がファイルを3回読み直す方が良いと思っています。 –

1

あなたのタイトルは間違っています、その機能は明らかに複数回実行されます。さもなければあなたは空のdictsを取り戻さないでしょう。空のディクテーションの理由は、csv.readerが既にイテレータのように動作するオブジェクトを返すからです。だから、それは一度だけ繰り返すことができます。次の2回の呼び出しでそれ以上のデータは取得されません。 csv.readerに再度電話するか、データをメモリに読み込んで3回処理する必要があります。

0

Iリーダを含み、ファイルの場所ではなく、リードインCSVを渡す機能を改変。

import csv 


def region_goals(csvfile, region, region_dictionary): 
    weeklist = csv.reader(open(csvfile)) 
    firstline = True 
    for row in weeklist: 
     if firstline: 
      firstline = False 
      continue 
     if row[14] == region: 
      if row[16] not in region_dictionary: 
       region_dictionary[row[16]] = float(row[6]) 
      else: 
       region_dictionary[row[16]] += float(row[6]) 
     else: 
      continue 
    return region_dictionary 

ありがとうございました!

関連する問題