2016-07-27 43 views
1

我已经看到similar question这个,但我认为我的困境是不同的足够的方式来保证一个新的问题。为什么python字典使用这么多内存?

我已经创建了一个函数,它打开一个csv文件并根据维度和指标列表将数据聚合成类似json的字典结构。

问题是,当我用它打开一个0.97GB的文件时,当我查看我的进程时,python进程正在使用大约1.02GB的内存。请记住,我只选择了文件中的一小部分字段,数据是总计,在那里我会认为它应该更小。此外,字典变量是从函数返回的唯一东西,所以不应该这意味着它是在函数运行后剩余在内存中的唯一东西吗?有谁知道为什么我的字典对象使用这么多的内存?

**编辑 - 也是我的理解是,csv.reader()是一个生成器,所以我甚至没有一次加载整个文件,所以它必须是使用所有内存的字典对象?

我在Windows上使用Python 2.7。

import json 
import inspect 
from pprint import pprint 
import csv 
from datetime import datetime 
import sys 


def jsonify_csv(fileString, dimensions, metrics, struc = {}): 
    with open(fileString, 'rb') as f: 
     reader=csv.reader(f) 
     headings = reader.next() 
     i = 0 
     for line in reader: 
      i+=1 
      row = {headings[i]:v for i, v in enumerate(line)} 
      pointer = struc 
      for dimension in dimensions: 
       if dimension == 'date': 
        val = str(datetime.strptime(row[dimension], "%d/%m/%Y").date().month) 
       else: 
        val = str(row[dimension]) 
       pointer.setdefault(val, {}) 
       pointer = pointer[val] 
      for metric in metrics: 
       pointer.setdefault(metric, 0.0) 
       try: 
        pointer[metric] += float(row[metric]) 
       except ValueError: 
        pass 
    return struc 


start = datetime.today() 

dims = ['brand', 'source', 'affiliate', 'country', 'store', 'salesbundle', 'product', 'ordertype', 'returncode', 'supplier', 'category'] 

metrics = ['sales', 'qty', 'cogs', 'carriagereclaim', 'Carriage Charged Carrier', 'carriage_est', 'mktg_est', 'mktg_cost', 'royalty', 'finance', 'scrap_cost', 'mp_cost', 'budgetsales', 'budgetcosts', 'BSTD', 'budgetaftersales', 'budgetscrap', 'budgetcarriagerecovery', 'budgetcarriagepaid', 'budgetmetapack', 'budgetmarketing', 'budgetaffiliate', 'budgetoffline', 'budgetroyalty', 'budgetfinance', 'bundle_qty', 'misc_adjustments'] 

jsonified = jsonify_csv('PhocasSales_2015+.csv', dims, metrics) 

print 'file opened', datetime.today()-start 

stop = raw_input("waiting...") 
+0

不要使用可变对象作为默认参数。见http://docs.python-guide.org/en/latest/writing/gotchas/ – cdarke

+0

嗨@cdarke谢谢你的回答,请你详细说明原因?我包含struc = {}的原因是为了例如打开5个单独的文件,并将它们全部存储在同一对象的不同分支中。例如x = {file1:{},file2:{}} –

+0

每个调用将使用相同的字典。你读过我给的链接了吗?在编译时创建空字典'{}'作为函数的一个属性。如果您使用默认值调用该函数28次,则不会获得28个不同的字典,它们将共享同一个字典。默认为“None”,然后在函数主体中测试它的值。 – cdarke

回答

2

每个调用将使用相同的字典。见http://docs.python-guide.org/en/latest/writing/gotchas/。在编译时创建空字典{}作为函数的属性。

如果您使用默认值调用了函数28次,您将不会获得28个不同的字典,它们将共享同一个字典。默认为None,然后在函数主体中测试它的值。

试试这个:

def jsonify_csv(fileString, dimensions, metrics, struc = None): 
    if struc is None: 
     struc = {} 

    with open(fileString, 'rb') as f: 
    ... # and so on 
+0

我已经解决了这个问题,但仍然不确定为什么单个函数调用给了我一个使用这么多内存的对象。 –

相关问题