【问题标题】:Using a for loop to insert list values in empty lists within a nested dictionary使用 for 循环在嵌套字典的空列表中插入列表值
【发布时间】:2019-04-09 11:17:57
【问题描述】:

我有一个嵌套字典:

my_dict = {
1: {'player_id': 1,
'player_name': 'Bryan_Demapan',
'time_played': 0.0,
'player_pokemon': {},
'gyms_visited': []},
2: {'player_id': 2,
'player_name': 'Tom Syneal',
'gyms_visited': [],
'player_pokemon': {},
'time_played': 0.0}}

假设我有一个列表

new_list = ['A', 'B', 'C']

如何创建一个 for 循环语句,将我的新列表插入到所有带有键“gyms_visited”的空列表中?

新字典应该是这样的

my_dict = {
1: {'player_id': 1,
'player_name': 'Bryan_Demapan',
'time_played': 0.0,
'player_pokemon': {},
'gyms_visited': ['A', 'B', 'C']},
2: {'player_id': 2,
'player_name': 'Tom Syneal',
'gyms_visited': ['A', 'B', 'C'],
'player_pokemon': {},
'time_played': 0.0}}

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我对预期的输出进行了编辑。
  • 他们每个人应该有一份列表的副本还是对同一个列表的引用?
  • 复制或引用同一列表即可
  • 键是序号的字典应该是一个列表。

标签: python dictionary for-loop


【解决方案1】:

只需遍历my_dict 的值并将new_list 分配给键'gyms_visited'

In [529]: for k, v in my_dict.items():
     ...:     v['gyms_visited'] = new_list.copy()
     ...:

In [530]: my_dict
Out[530]:
{1: {'gyms_visited': ['A', 'B', 'C'],
  'player_id': 1,
  'player_name': 'Bryan_Demapan',
  'player_pokemon': {},
  'time_played': 0.0},
 2: {'gyms_visited': ['A', 'B', 'C'],
  'player_id': 2,
  'player_name': 'Tom Syneal',
  'player_pokemon': {},
  'time_played': 0.0}}

如果您只是简单地分配new_list,那么一旦您更改new_list 中的任何值,您就会遇到麻烦

In [529]: for k, v in my_dict.items():
     ...:     v['gyms_visited'] = new_list
     ...:

In [531]: new_list[1] = 100

In [532]: my_dict
Out[532]:
{1: {'gyms_visited': ['A', 100, 'C'],
  'player_id': 1,
  'player_name': 'Bryan_Demapan',
  'player_pokemon': {},
  'time_played': 0.0},
 2: {'gyms_visited': ['A', 100, 'C'],
  'player_id': 2,
  'player_name': 'Tom Syneal',
  'player_pokemon': {},
  'time_played': 0.0}}

【讨论】:

  • 谢谢。这正是我需要更改字典的 for 循环。
【解决方案2】:

您可以使用字典理解:

new_list = ['A', 'B', 'C']
data = {1: {'player_id': 1, 'player_name': 'Bryan_Demapan', 'time_played': 0.0, 'player_pokemon': {}, 'gyms_visited': []}, 2: {'player_id': 2, 'player_name': 'Tom Syneal', 'gyms_visited': [], 'player_pokemon': {}, 'time_played': 0.0}}
new_data = {a:{c:[i for i in new_list if i not in d] if c == 'gyms_visited' else d \
    for c, d in b.items()} for a, b in data.items()}

输出:

{
  "1": {
    "player_id": 1,
    "player_name": "Bryan_Demapan",
    "time_played": 0.0,
    "player_pokemon": {},
    "gyms_visited": ["A", "B", "C"]
 },
 "2": {
    "player_id": 2,
    "player_name": "Tom Syneal",
    "gyms_visited": ["A", "B", "C"],
    "player_pokemon": {},
    "time_played": 0.0
   }
}

【讨论】:

  • 与 aydow 回答中的简单 for 循环相比,这似乎非常复杂。
  • @Barmar 是的,尽管我通常更喜欢创建一个新结构,而不是尝试就地改变现有结构。
  • @Barmar 我的也是,我对此感到遗憾,哈哈,所以在 aydow 的小漂亮循环中添加了额外的东西......
【解决方案3】:

试试这个:

print({idx:{k:(new_list if k=='gyms_visited' else v) for k,v in i.items()} for idx,i in enumerate(my_dict.values(),1)})

嵌套字典理解会起作用。

输出:

{1: {'player_id': 1, 'player_name': 'Bryan_Demapan', 'time_played': 0.0, 'player_pokemon': {}, 'gyms_visited': ['A', 'B', 'C']}, 2: {'player_id': 2, 'player_name': 'Tom Syneal', 'gyms_visited': ['A', 'B', 'C'], 'player_pokemon': {}, 'time_played': 0.0}}

我其实很喜欢@aydow的解决方案,除此之外,你还可以这样做:

for k,v in data.items():
   v['gyms_visited']=new_list[:]

或者:

import copy
for k,v in data.items():
   v['gyms_visited']=copy.deepcopy(new_list)

【讨论】:

    【解决方案4】:

    你也可以只extend()列表:

    for key in my_dict:
        my_dict[key]['gyms_visited'].extend(new_list)
    

    正如您在此处看到的,所有列表都有不同的id(),并且没有引用同一个对象:

    print(id(new_list))
    # 2704861952904
    
    for key in my_dict:
        print(id(my_dict[key]['gyms_visited']))
    # 2704833143368
    # 2704833143432
    

    在性能方面,list.extend() 是 O(N),其中 N = 3 是您要扩展的列表的长度。这很可能是一系列 list.append() 调用,每个调用都是 O(1)。

    这对于使用[:].copy() 进行复制是相同的,即O(N)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 2022-01-13
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多