将字典附加到列表中时出现奇怪行为
我正在将JSON读入我的脚本并构建一个由字典组成的列表。将字典附加到列表中时出现奇怪行为
我的JSON:
{
"JMF": {
"table1": {
"email": "[email protected]",
"guests": [
"test1",
"test2"
]
},
"table2": {
"email": "[email protected]",
"guests": [
"test3"
]
}
},
"JMC": {
"table3": {
"email": "[email protected]",
"guests": [
"test11"
]
}
},
"JMD": {
"table4": {
"email": "[email protected]",
"guests": [
"test12"
]
},
"table5": {
"email": "[email protected]",
"guests": [
"test17"
]
}
}
}
我的代码:
def get_json():
userinfo_list = []
with open('guest_users.json') as json_file:
json_file = json.load(json_file)
keys = json_file.keys()
for key in keys:
userinfo = {}
for table_key in json_file[key].keys():
email = json_file[key][table_key]['email']
users_dict = {}
users_list = []
for user in json_file[key][table_key]['guests']:
users_dict['username'] = user
users_dict['password'] = generate_password()
users_list.append(users_dict)
userinfo['company'] = key
userinfo['email'] = email
userinfo['userinfo'] = users_list
userinfo_list.append(userinfo)
print(userinfo)
print(userinfo_list)
的问题是,我的JSON有两个子键(table*
)在userinfo_list
价值得到尽快覆盖。
这是输出我得到的,这没有任何意义:
{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}]
{'userinfo': [{'username': 'test17', 'password': 'A8Jue5'}], 'email': '[email protected]', 'company': 'JMD'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}, {'userinfo': [{'username': 'test17', 'password': 'A8Jue5'}], 'email': '[email protected]', 'company': 'JMD'}]
{'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}]
{'userinfo': [{'username': 'test2', 'password': 'GagQ59'}, {'username': 'test2', 'password': 'GagQ59'}], 'email': '[email protected]', 'company': 'JMF'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}, {'userinfo': [{'username': 'test2', 'password': 'GagQ59'}, {'username': 'test2', 'password': 'GagQ59'}], 'email': '[email protected]', 'company': 'JMF'}]
{'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': '[email protected]', 'company': 'JMF'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': '[email protected]', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': '[email protected]', 'company': 'JMD'}, {'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': '[email protected]', 'company': 'JMF'}, {'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': '[email protected]', 'company': 'JMF'}]
您重新追加同一个字典每次迭代:
users_dict = {} # only one copy of this dictionary is ever created
users_list = []
for user in json_file[key][table_key]['guests']:
users_dict['username'] = user
users_dict['password'] = generate_password()
users_list.append(users_dict) # appending a reference to users_dict
追加不不创建副本,因此您可以获得对同一字典的多个引用,并且只会看到反映的最后更改。您在userinfo
字典中犯了同样的错误。
创建一个新的字典在循环:
users_list = []
for user in json_file[key][table_key]['guests']:
users_dict = {}
users_dict['username'] = user
users_dict['password'] = generate_password()
users_list.append(users_dict)
创建字典时,你可以直接指定键值对:
users_list = []
for user in json_file[key][table_key]['guests']:
users_dict = {
'username': user,
'password': generate_password()
}
users_list.append(users_dict)
,这可以用一个简化list comprehension至:
users_list = [{'username': user, 'password': generate_password()}
for user in json_file[key][table_key]['guests']]
请注意,您无需拨打dict.keys()
即可循环查看字典。您可以直接循环通过字典具有完全相同的结果。你可能要循环.items()
代替,并避免查找关键每次的价值,并使用.values()
当你实际上并不需要的关键都:
userinfo_list = []
for company, db in json_file.items():
for table in db.values():
userinfo = {
'company': company,
'email': table['email'],
'userinfo': [
{'username': user, 'password': generate_password()}
for user in table['guests']]
}
userinfo_list.append(userinfo)
每桌字典的创建每个公司也可以用列表理解取代,但是在这一点上坚持嵌套for
循环可能会更容易理解未来的读者。
上面现在生产:
[{'company': 'JMF',
'email': '[email protected]',
'userinfo': [{'password': 'random_password_really', 'username': 'test1'},
{'password': 'random_password_really', 'username': 'test2'}]},
{'company': 'JMF',
'email': '[email protected]',
'userinfo': [{'password': 'random_password_really', 'username': 'test3'}]},
{'company': 'JMC',
'email': '[email protected]',
'userinfo': [{'password': 'random_password_really', 'username': 'test11'}]},
{'company': 'JMD',
'email': '[email protected]',
'userinfo': [{'password': 'random_password_really', 'username': 'test12'}]},
{'company': 'JMD',
'email': '[email protected]',
'userinfo': [{'password': 'random_password_really', 'username': 'test17'}]}]
从样本数据(和我自己的generate_password()
定义)。
这个工作完美,但我无法适应你的代码到我更新的JSON。请参阅我的原始帖子以获取更新的JSON。 – rhillhouse
@ou_snaaksie:那通常是一个新问题。你需要在这里过滤每个'db'字典的键:'对于tablename,db.items()中的表:'',如果不是tablename.startswith('table'):continue'(而不是当前的'for table在分贝。values():'loop)会跳过任何不以''table'开头的键,比如''lang''。 –
不要覆盖数据。总是尝试创建新的列表,新的字典,新的一切 - 如果RAM内存允许你 - 并且它可以让你在99%的情况下。 –