我很难理解如何正确地迭代csvDictReader对象。用户定义的csv值返回我绑定的每个代码。因为我是从一个web查询生成dict,所以我希望在内存中重用它,而不是再次在web上轮询已经存在于内存中的数据。在
import sys, csv, urllib2
class SmfImpl():
def __init__( self, ctx ):
self.ctx = ctx
self.csv_dict = []
self.flag = ['Not Available', '']
self.ticker = 'XOM'
def getMorningKey(self, datacode):
return fetch_keyratios(self, datacode)
#these functions are not in the SmfImpl class because they're from a seperate file
def query_morningstar(self, url_ending):
url = 'http://financials.morningstar.com/ajax/exportKR2CSV.html?&callback=?&t=XNYS:%s%s' % (self.ticker, url_ending)
req = urllib2.Request(url)
response = sniff_query(req)
response.readline()
return csv.DictReader(response)
def sniff_query(req):
try:
response = urllib2.urlopen(req)
except urllib2.URLError:
return 'Check Connection'
sniff = response.readline()
if str(sniff) == '':
return 'Not Available'
return response
def fetch_keyratios(self, datacode):
if datacode < 1 or datacode > 990:
return 'Invalid Datacode'
#check if we already have the data we need
if self.flag[0] == 'Check Connection' or self.flag[0] == 'Not Available' or self.flag[1] != self.ticker:
#query remote and check for errors
self.csv_dict = query_morningstar(self,'®ion=usa&culture=en-US&cur=USD&order=desc')
if self.csv_dict == 'Check Connection' or self.csv_dict == 'Not Available':
self.flag[1] = ''
return self.csv_dict
else:
self.flag[0] = ''
self.flag[1] = self.ticker
return sort_keyratios(self, datacode)
def sort_keyratios(self, datacode):
counter = 1
skipped = 0
skip_lines = [15, 16, 26, 36, 37, 57, 58, 64, 65, 86, 91, 92]
#iterate through returned dict line by line
for line in self.csv_dict:
for item in skip_lines:
if counter == item:
skipped += 1
for val in range(1, len(line)):
#match year values to datacodes
if datacode == val:
return self.csv_dict.fieldnames[val]
#match data values to datacodes
if datacode-((counter-skipped)*(len(line)-1)) == val:
return line[self.csv_dict.fieldnames[val]]
counter += 1
return 'No Data'
if __name__ == "__main__":
smf = SmfImpl(sys.argv)
ticker = 'XOM'
for val in range (1,24):
print ticker, val,':', smf.getMorningKey(val)
原始csv由脚本调用,但也可以找到here
我得到的输出是:
^{pr2}$我想要的是:
XOM 1 : TTM
XOM 2 : 2012-12
XOM 3 : 2011-12
XOM 4 : 2010-12
XOM 5 : 2009-12
XOM 6 : 2008-12
XOM 7 : 2007-12
XOM 8 : 2006-12
XOM 9 : 2005-12
XOM 10 : 2004-12
XOM 11 : 2003-12
XOM 12 : 443,708
XOM 13 : 482,295
XOM 14 : 486,429
XOM 15 : 383,221
XOM 16 : 310,586
XOM 17 : 477,359
XOM 18 : 404,552
XOM 19 : 377,635
XOM 20 : 370,680
XOM 21 : 298,035
XOM 22 : 246,738
XOM 23 : 27.8
编辑:我正在尝试映射数据代码分组每行原始csv。e、 g年将是数据代码1到11(TTM到2003-12),收入将是数据代码12到22(443708到246738)等等。最终这些数据代码将被移动到用户输入中,因此可以以任何顺序访问它们。在
下面是我该怎么做的。它将产生你想要的输出。我已经重新格式化了一些代码,以便更好地适应stackoverflow上的代码列表框。棘手的部分是找出读入内存中矩阵的数据的}的映射。在
datacode
到{使用
csv.reader()
代替csv.DictReader
,因为您并没有真正使用列/字段名。第一次调用getMorningKey()
时,响应中的所有数据(除了少数第一行)都被读入并存储在一个列表列表中。以这种方式读取的每一行都应该是12个项目的列表,任何未跳过的项目都将被跳过。此外,为了使数据代码的映射更容易,只保存最后11个条目。结果是一个二维矩阵,其中行是行号,列是字段号。我创建的这个web page上显示了Exxon示例ticker的原始矩阵数据视图。在正如您所看到的,这种方法极大地简化了逻辑,而且由于它将所有数据存储在内存中,因此它将在后续调用中重用,并使随机访问成为可能,而无需再次执行查询。在
输出如下:
^{pr2}$马蒂诺贴出的答案是正确的。为了完成并获得我最初寻找的功能,我将sort\u keyriotios更改为以下内容:
这是对您在自己的问题的答案中对
sort_keyratios()
所做的修改作出的回应。如果你发现其他有用的信息,你还有其他事情要投票。<;提示>总之,您可以更有效地完成正在做的事情,方法是构建一个字典,将每个
datacode
映射到一个(row, col)
对,然后使用这个先前构建的表来查找函数中的值。为了方便起见,我添加了一个名为create_datacode_map()
的新函数。在以下是如何使用它:
所示的
sort_keyratios()
版本在每次调用时都检查self.datacode_map
是否存在,如果不存在,则创建它。如果已经在fetch_keyratios(()
中完成了该操作,那么sort_keyratios()
就可以假定它存在,而不必每次调用它时都进行检查。在相关问题 更多 >
编程相关推荐