Sono abbastanza nuovo alla programmazione e ho creato un programma per recuperare i dati di inventario dai giocatori di Team Fortress 2 e mettere gli oggetti di inventario in un dizionario con steamid come chiave e l'elenco di elementi come valore .Python dictionary eat up ram
Il problema che sto incontrando è che dopo circa 6000 voci nel dizionario il programma ha risucchiato essenzialmente tutta la RAM sul mio sistema e si spegne.
Immagino che il dizionario diventi troppo grande ma da quello che ho letto da domande simili un dittico di 6000 voci non dovrebbe occupare gran parte della mia RAM.
Ho esaminato altre soluzioni, ma potrei utilizzare alcuni esempi concreti per il mio codice.
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")
io non so davvero di qualsiasi altro modo per farlo, pur mantenendo la comparsa dizionario, che è abbastanza importante in quanto mi piacerebbe essere in grado di dire di chi l'inventario che è. Se sono stato poco chiaro in tutto questo, basta dirlo e cercherò di spiegare
Aggiungendo così: inventory = dict() items = list() all'inizio del ciclo "for steamid in steamprofiler" dovrebbe impedire l'hogging della memoria a qualche grado? Non capisco perfettamente il problema con il ciclo di inventario, i valori chiave nell'inventario corrispondono ai nomi in index_to_name e index_to_quality, come fa la soluzione a fare meglio? Non sto dando la bocca qui, sono sinceramente curioso dato che sono abbastanza nuovo. – Tenbin
Per quanto riguarda il ciclo su "inventario", ho pensato che fosse un po 'strano che tu stessi accedendo a "inventario [chiave] [0]" e "inventario [chiave] [0]" e non accedendo a "chiave" da nessun'altra parte. Se questi sono i valori che devi usare (per l'indicizzazione nei tuoi altri dizionari), ti suggerisco di fare direttamente il ciclo iterato su di essi. Se 'inventory [key]' è una tupla o lista di due elementi, puoi scompattarla in due variabili direttamente nell'istruzione 'for'. Modificherò la mia risposta per mostrare come sarebbe, con indentazione corretta. – Blckknght