Jestem całkiem nowy w programowaniu i stworzyłem program do pobierania danych o inwentarzu z odtwarzaczy Team Fortress 2 i umieszczania elementów w ekwipunku w słowniku z steamidem jako kluczem i listą pozycji jako wartości .Słownik Pythona zjada ram
Problem polega na tym, że po około 6000 wpisach do słownika program całkowicie zasysał całą pamięć RAM w moim systemie i wyłącza się.
Zgaduję, że słownik staje się po prostu zbyt duży, ale według tego, co przeczytałem z podobnych pytań, dykta 6000 wpisów nie powinna zajmować tak dużej części pamięci RAM.
Szukałem innych rozwiązań, ale mógłbym użyć konkretnych przykładów dla mojego kodu.
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")
ja naprawdę nie wiem o inny sposób to zrobić zachowując słownika appearence, co jest dość ważne, ponieważ chciałbym, aby móc powiedzieć, których asortyment jest. Jeśli byłem niejasny w cokolwiek z tego, po prostu powiedzieć tak i postaram się wyjaśnić
A więc dodanie: inventory = dict() items = list() na początku pętli "for steamid in steamprofiler" powinno uniemożliwić wgranie pamięci do pewien stopień? Nie bardzo rozumiem problem z pętlą inwentaryzacji, kluczowe wartości w ekwipunku odpowiadają imionom w index_to_name i index_to_quality, w jaki sposób twoje rozwiązanie robi to lepiej? Nie mówię tutaj, jestem naprawdę ciekawy, bo jestem całkiem nowy. – Tenbin
Jeśli chodzi o pętlę nad 'inwentarzem', to po prostu było trochę dziwne, że korzystałeś z' inventory [key] [0] 'oraz' inventory [key] [0] 'i nie uzyskując dostępu do' klucza' gdziekolwiek indziej. Jeśli są to wartości, których musisz użyć (do indeksowania w innych słownikach), sugeruję, aby pętla była iterowana bezpośrednio na nich. Jeśli 'inventory [key]' jest dwuelementową krotką lub listą, możesz rozpakować ją do dwóch zmiennych bezpośrednio w instrukcji 'for'. Zmienię moją odpowiedź, aby pokazać, jak to będzie wyglądać, z odpowiednim wcięciem. – Blckknght