簡體   English   中英

Python字典吃掉了ram

[英]Python dictionary eating up ram

我對編程很陌生,並且制作了一個程序來從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")

我真的不知道在保留字典外觀的情況下還有其他方法可以這樣做,這非常重要,因為我想知道它是誰的清單。 如果我不清楚其中的任何一個,那就這么說,我會盡力解釋

我認為您的代碼中存在一些邏輯錯誤。 例如,您要將每個玩家的庫存物品添加到inventory字典中,然后對其進行迭代以填充其他內容。

但是,您永遠不會重置inventory字典,因此它將繼續累積物品(因此,第二位玩家似乎除了擁有第一人的庫存外,還會擁有第一人的庫存)。

稍后使用的items字典也有類似的問題。 您將其重置為本來是空列表的emptyitems ,但是由於Python中的賦值是通過引用進行的,因此沒有任何效果( items已經與emptyitems是同一對象)。

有了這兩個修復程序,您可能有更大的機會不使用系統的所有內存。

另一個其他代碼改進(可能與內存使用無關):

inventory ,您反復訪問相同的兩個值,而不使用任何key 除了在for key in inventory嘗試for value1, value2 in inventory.itervalues() (或者in inventory.values()使用Python 3的情況下for value1, value2 in inventory.itervalues()嘗試for value1, value2 in inventory.itervalues() 然后使用value1代替inventory[key][0]並使用value2代替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)]
                )

我相信這說明了您的代碼存在問題:

>>> emptyitems=[]
>>> a=emptyitems
>>> a.append("hello")
>>> a.append("bar")
>>> a
['hello', 'bar']
>>> emptyitems
['hello', 'bar']

換句話說,您正在捕獲對emptyitems列表的引用,該列表確實會變得非常大。 這可能不是您的意思,並且我可以想象要處理大量列表會變得非常占用內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM