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

谢谢所有回复!