吞噬公羊的Python字典

Ten*_*bin 5 python ram dictionary steam

我对编程非常陌生,并制作了一个程序,用于从Team Fortress 2玩家那里获取库存数据,并将库存项目放入字典中,其中以steamid为键,项目列表为值.

我遇到的问题是,在大约6000个词条进入字典后,程序已经基本上吸收了我系统上的所有RAM并关闭了.

我猜这本字典只是变得太大了但是我从类似的问题中读到了6000个条目的字典不应该占用我的RAM.

我一直在寻找其他解决方案,但我可以使用一些具体的例子来代码.

import re, urllib.request, urllib.error, gzip, io, json, socket, sys

with open("index_to_name.json", "r", encoding=("utf-8")) as fp:
    index_to_name=json.load(fp)

with open("index_to_quality.json", "r", encoding=("utf-8")) as fp:
    index_to_quality=json.load(fp)

with open("index_to_name_no_the.json", "r", encoding=("utf-8")) as fp:
    index_to_name_no_the=json.load(fp)

with open("steamprofiler.json", "r", encoding=("utf-8")) as fp:
    steamprofiler=json.load(fp)

inventory=dict()
playerinventories=dict()
c=0

for steamid in steamprofiler:
    emptyitems=[]
    items=emptyitems
    try:
        url=urllib.request.urlopen("http://api.steampowered.com/IEconItems_440/GetPlayerItems/v0001/?key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&steamid="+steamid+"&format=json")
        inv=json.loads(url.read().decode("utf-8"))
        url.close()
    except (urllib.error.HTTPError, urllib.error.URLError, socket.error) as e:
        c+=1
        print("URL/HTTP error, continuing")
        continue
    try:
        for r in inv["result"]["items"]:
            inventory[r["id"]]=r["quality"], r["defindex"]
    except KeyError:
        c+=1
        print(steamid, "didn't have an inventory")
        continue
    for key in inventory:
        try:
            if index_to_quality[str(inventory[key][0])]=="":
                items.append(
                    index_to_quality[str(inventory[key][0])]
                    +""+
                    index_to_name[str(inventory[key][1])]
                    )
            else:
                items.append(
                    index_to_quality[str(inventory[key][0])]
                    +" "+
                    index_to_name_no_the[str(inventory[key][1])]
                    )
        except KeyError:
            print("Key error, uppdate def_to_index")
            c+=1
            continue
playerinventories[int(steamid)]=items
items=emptyitems
c+=1
print(c, "inventories fetched")
Run Code Online (Sandbox Code Playgroud)

我真的不知道任何其他方式做到这一点,同时保留字典appearence,这是因为我希望能告诉他们的库存还是比较重要的.如果我不清楚这一点,请说出来,我会试着解释一下

Blc*_*ght 4

我认为您的代码中有一些逻辑错误。例如,您将每个玩家的库存项目添加到字典中inventory,然后迭代它以填充其他内容。

但是,您永远不会重置inventory字典,因此它会继续积累物品(因此第二个玩家除了自己的库存之外,还会出现第一个人的库存)。

items您稍后使用的词典也遇到了类似的问题。您将其重置为emptyitems最初是一个空列表,但由于 Python 中的赋值是通过引用进行的,因此这没有任何效果(items已经与 相同的对象emptyitems)。

通过这两个修复,您可能有更好的机会不使用所有系统内存。

另一个杂项代码改进(可能与内存使用无关):

在您的循环 over 中inventory,您重复访问相同的两个值并且不使用key任何内容。而不是for key in inventory尝试for value1, value2 in inventory.itervalues()(或者in inventory.values()如果您使用的是 Python 3)。然后使用value1in place ofinventory[key][0]value2in place of inventory[key][1](或者更好的是,给它们起更有意义的名字)。

编辑:循环可能如下所示(我有点猜测之前在inventory[key][0]和中的两个值的名称inventory[key][1]):

for quality, name in inventory.itervalues():
    try:
        if index_to_quality[str(quality)]=="":
            items.append(
                index_to_quality[str(quality)]
                +""+
                index_to_name[str(name)]
                )
        else:
            items.append(
                index_to_quality[str(quality)]
                +" "+
                index_to_name_no_the[str(name)]
                )
Run Code Online (Sandbox Code Playgroud)