2016-10-03 8 views
0

私はスクリプトに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'}] 
+0

データを上書きしないでください。新しいリスト、新しいdicts、新しいものを作成しようとすると、RAMメモリが許せば、99%のケースで処理できます。 –

答えて

2

あなたは同じ単一の辞書各反復再追加されます。

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) 

、これはAで簡略化することが可能にlist comprehension to:

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()の私自身の定義)から。

+0

これは完全に動作しますが、私はあなたのコードを私の更新されたJSONに適合させることができませんでした。更新されたJSONのオリジナルの投稿をご覧ください。 – rhillhouse

+0

@ou_snaaksie:これは通常新しい質問になるでしょう。 tablename、db.items()内のテーブル: '、' not tablename.startswith( 'table'):continue'(現在の 'for tableの代わりに、' db'辞書のキーをフィルタリングする必要があります。 db。values(): 'loop)は' 'lang''のように' 'table ''で始まらないキーをスキップします。 –

関連する問題