向lis添加词典时的奇怪行为

2024-10-02 22:31:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将JSON读入我的脚本并构建一个由字典组成的列表。你知道吗

我的JSON:

{
    "JMF": {
        "table1": {
          "email": "JMF1@fake.com",
          "guests": [
            "test1",
            "test2"
          ]
        },
        "table2": {
          "email": "JMF2@fake.com",
          "guests": [
            "test3"
          ]
        }
    },
    "JMC": {
      "table3": {
        "email": "JMC1@fake.com",
        "guests": [
          "test11"
        ]
      }
    },
    "JMD": {
      "table4": {
        "email": "JMD1@fake.com",
        "guests": [
          "test12"
        ]
      },
      "table5": {
        "email": "JMD2@fake.com",
        "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': 'JMC1@fake.com', 'company': 'JMC'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': 'JMC1@fake.com', 'company': 'JMC'}]
{'userinfo': [{'username': 'test17', 'password': 'A8Jue5'}], 'email': 'JMD2@fake.com', 'company': 'JMD'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': 'JMC1@fake.com', 'company': 'JMC'}, {'userinfo': [{'username': 'test17', 'password': 'A8Jue5'}], 'email': 'JMD2@fake.com', 'company': 'JMD'}]
{'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': 'JMC1@fake.com', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}]
{'userinfo': [{'username': 'test2', 'password': 'GagQ59'}, {'username': 'test2', 'password': 'GagQ59'}], 'email': 'JMF1@fake.com', 'company': 'JMF'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': 'JMC1@fake.com', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}, {'userinfo': [{'username': 'test2', 'password': 'GagQ59'}, {'username': 'test2', 'password': 'GagQ59'}], 'email': 'JMF1@fake.com', 'company': 'JMF'}]
{'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': 'JMF2@fake.com', 'company': 'JMF'}
[{'userinfo': [{'username': 'test11', 'password': '1fEAg0'}], 'email': 'JMC1@fake.com', 'company': 'JMC'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}, {'userinfo': [{'username': 'test12', 'password': '0JSpc0'}], 'email': 'JMD1@fake.com', 'company': 'JMD'}, {'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': 'JMF2@fake.com', 'company': 'JMF'}, {'userinfo': [{'username': 'test3', 'password': 'U9gP0j'}], 'email': 'JMF2@fake.com', 'company': 'JMF'}]

Tags: keycomjsonemailusernamepassworduserscompany
1条回答
网友
1楼 · 发布于 2024-10-02 22:31:07

每次迭代都要重新附加同一个字典

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': 'JMF1@fake.com',
  'userinfo': [{'password': 'random_password_really', 'username': 'test1'},
               {'password': 'random_password_really', 'username': 'test2'}]},
 {'company': 'JMF',
  'email': 'JMF2@fake.com',
  'userinfo': [{'password': 'random_password_really', 'username': 'test3'}]},
 {'company': 'JMC',
  'email': 'JMC1@fake.com',
  'userinfo': [{'password': 'random_password_really', 'username': 'test11'}]},
 {'company': 'JMD',
  'email': 'JMD1@fake.com',
  'userinfo': [{'password': 'random_password_really', 'username': 'test12'}]},
 {'company': 'JMD',
  'email': 'JMD2@fake.com',
  'userinfo': [{'password': 'random_password_really', 'username': 'test17'}]}]

从您的示例数据(以及我自己对generate_password()的定义)。你知道吗

相关问题 更多 >