2016-05-17 185 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 

輸出始終如預期的第一次使用的功能。第二次我使用這個函數,返回空字典。

我敢肯定,這是我缺少一些小東西,但我是python新手,一直在努力解決這個問題。預先感謝您的回覆。

+0

您已經在第一次調用中迭代了文件,因此後面的調用沒有任何可讀的內容。您可能需要將調用移動到'weekList = csv.reader(open(csvFile))'到函數中(所以文件被重新打開),或者如果csv.reader類支持,您可以嘗試'weekList.seek(0)'它。 –

+1

如果函數返回三個字典,那麼顯然它會運行三次。 –

+0

不錯的嘗試阿納布,但如果你看看上面的內容,在設置過程中會創建三個空字典。 –

回答

2

第一次通過後,您處於CSV文件的末尾,沒有什麼可以閱讀的,因此您需要重新打開它。

此外,用函數就地修改對象並不是最好的想法。每次都返回一個新對象會更好。

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 
f = open(csvFile) 
weekList = csv.reader(f) 

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

編輯: 如果文件是沒有太大和/或你處理更多的內存使用率,你可以這樣做:

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

您的代碼應工作,但請記住整個文件將被加載到內存中。

最好的解決方案是重構一些東西,在一次傳遞中填充這三個字符並調用該函數一次。

+0

它應該可能是'f = open(csvFile)'。 – Achim

+0

你的意思是'weekList.seek(0)'? –

+0

我不得不認爲,將文件一次讀入「list」並將該列表*傳遞給該函數會更好,而不是重新讀取該文件3次。 –

1

您的標題在某種意義上是錯誤的,該功能顯然是多次執行的。否則,你不會收回空的字典。空字符的原因是,csv.reader已經返回一個像迭代器一樣的對象。所以你只能迭代一次。接下來的兩個調用將不會獲得更多數據。您必須再次撥打csv.reader,否則您必須將數據讀入內存並處理三次。

0

根據g.d.d.c的建議我修改了函數以包含reader和傳遞文件位置而不是讀入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 

謝謝所有回覆!