Python 将新数据迭代到嵌套字典中



我一直在开发一个Python角色扮演游戏,我有一个从文本文件导入项目数据的功能。文本文件的结构如下:

WEAPON 3 sword_of_eventual_obsolescence 6 10 2 0 10
WEAPON 4 dagger_of_bluntness 2 5 3 1 0
WEAPON 5 sword_of_extreme_flimsiness 3 8 3 7 0

数据导入如下所示:

def items_get():
import os
global items
items = {
"weapon":{},
"armour":{},
"potion":{},
"misc":{}
}
file_dir = ( os.getcwd() + 'Codeitems.txt' )
file_in = open( file_dir, 'r')
for each_line in file_in:
line = file_in.readline()
line = line.split(' ')
if line[0] == "WEAPON":
weapon_id = line[1]
name = line[2]
attack_min = line[3]
attack_max = line[4]
range = line[5]
weight = line[6]
value = line[7]
weapon_data = {
"name": name.replace('_', ' '),
"atk_min": attack_min,
"atk_max": attack_max,
"rng": range,
"wt": weight,
"val": value,
}
items["weapon"][weapon_id] = {}
items["weapon"][weapon_id].update(weapon_data)

但是,当我打印物品["武器"]时,我得到这个:

{'4': {'wt': '1', 'atk_min': '2', 'atk_max': '5', 'val': '0', 'name': 'dagger of bluntness', 'rng': '3'}}

如您所见,那里只有 1 个项目。在其他情况下,即使我实际上列出了 3 个项目,我也有两个。为什么会发生这种情况,如何获取字典中的所有 3 个项目?

谢谢! :P

编辑:这是药水的数据,如果你想知道的话。

elif line.split()[0] == "POTION":
_, id, name, hp_bonus, atk_bonus, range_bonus, ac_bonus, str_bonus, con_bonus, dex_bonus, int_bonus, wis_bonus, cha_bonus, wt, val = line.split()

治疗药水在文件中如下所示:

POTION 1 potion_of_healing 20 0 0 0 0 0 0 0 0 0 0.1 2
for each_line in file_in:
line = file_in.readline()

each_line已经包含下一行,因为循环访问类似文件的对象(例如,使用 for 循环(会导致它按行进行。

在循环的每次迭代中,文件指针前进一行(类似文件的对象,虽然可以倒带,但会跟踪它们上次访问的位置(,然后在完成任何操作之前,它再次前进readline(),因此唯一没有完全跳过的行是中间的一行 (4(。

要解决此问题,请直接在循环体中使用循环变量 (each_line( 并取消file_in.readline()

@noname1014,我知道你知道这一点,但我想指出你的代码的一些问题(在某些特殊情况下可能会出现,例如,如果你将文件名items.txt更改为new_items.txtrare_fruits.txt等(和一些建议。

不要在 Windows 中使用作为路径分隔符。使用\否则您可能会遇到问题。Codetime_items.txt将被评估为Code imeitems.txt因为t在这里是 TAB。

使用只在少数情况下有效,如果后跟任何字符Apnt"'等不构建转义序列,如ntfrb等。

请查看以下示例进行说明。

>>> import os
>>>
>>> print(os.getcwd() + 'Codetimeitems.txt')
E:UsersRishikeshPython3PracticeCode        imeitems.txt
>>>
>>> print(os.getcwd() + 'Code\timeitems.txt')
E:UsersRishikeshPython3PracticeCodetimeitems.txt
>>>
>>> print(os.getcwd() + 'Codenewitems.txt')
E:UsersRishikeshPython3PracticeCode
ewitems.txt
>>>
>>> print(os.getcwd() + '\Code\newitems.txt')
E:UsersRishikeshPython3PracticeCodenewitems.txt
>>>
>>> # Do not use it as it may work only in some cases if  followed by any character does not construct escape sequences.
...
>>> os.getcwd() + 'Codeitems.txt'
'E:\Users\Rishikesh\Python3\Practice\Code\items.txt'
>>>
>>> # Use \ as path separators
...
>>> os.getcwd() + '\Code\items.txt'
'E:\Users\Rishikesh\Python3\Practice\Code\items.txt'
>>>
>>> print(os.getcwd() + 'Codeitems.txt')
E:UsersRishikeshPython3PracticeCodeitems.txt
>>>
>>> print(os.getcwd() + '\Code\items.txt')
E:UsersRishikeshPython3PracticeCodeitems.txt
>>>

如果您的词典很大,并且在查看其项目时遇到任何问题,请使用json模块对其进行美化,它具有一个名为dumps()的函数,用于漂亮打印listdictionary对象。

可以将import语句放在函数中,但将其放在顶部是一种Python 方式(https://www.python.org/dev/peps/pep-0008/#imports(。它适用于在同一模块中具有多种功能的大型应用程序。

使用with语句打开文件,在这种情况下,您不需要关闭文件。

你的代码很好,我刚刚修改了它,如下所示。

import os
global items
import json
def items_get():
items = {
"weapon":{},
"armour":{},
"potion":{},
"misc":{}
}
# Do not use  as path separators in Windows. Use \ (t, n, ' have speacial meanings)
file_dir = ( os.getcwd() + '\Code\items.txt' )
with open( file_dir, 'r') as file_in:
lines = file_in.readlines();
# ['WEAPON 3 sword_of_eventual_obsolescence 6 10 2 0 10n', 'WEAPON 4 dagger_of_bluntness 2 5 3 1 0n', 'WEAPON 5 sword_of_extreme_flimsiness 3 8 3 7 0']
for each_line in lines:
# Use strip() to remove any leading/trailing whitespaces (n, t, spaces etc.)
line = each_line.strip().split(' ');
if line[0] == "WEAPON":
weapon_id = line[1]
name = line[2]
attack_min = line[3]
attack_max = line[4]
range = line[5]
weight = line[6]
value = line[7]
weapon_data = {
"name": name.replace('_', ' '),
"atk_min": attack_min,
"atk_max": attack_max,
"rng": range,
"wt": weight,
"val": value,
}
items["weapon"][weapon_id] = {}
items["weapon"][weapon_id].update(weapon_data)
return items 
# Calling items_get() to get dictionary
items = items_get();
# Pretty printing dictionary using json.dumps()
print(json.dumps(items, indent=4))

» 输出

{
"weapon": {
"3": {
"name": "sword of eventual obsolescence",
"atk_min": "6",
"atk_max": "10",
"rng": "2",
"wt": "0",
"val": "10"
},
"4": {
"name": "dagger of bluntness",
"atk_min": "2",
"atk_max": "5",
"rng": "3",
"wt": "1",
"val": "0"
},
"5": {
"name": "sword of extreme flimsiness",
"atk_min": "3",
"atk_max": "8",
"rng": "3",
"wt": "7",
"val": "0"
}
},
"armour": {},
"potion": {},
"misc": {}
}

最新更新