【问题标题】:iteratively appending N items to list gives last item N times instead迭代地将 N 个项目附加到列表中,而不是给出最后一个项目 N 次
【发布时间】:2020-05-23 20:37:18
【问题描述】:

我正在访问字典项目列表list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}],并尝试使用函数add_entries 有条件地将每个条目附加到另一个列表article_list

我想要的输出

article_list = [{x:1a, y:1b, z:1c}, {x:2a}, {x:3a, y:3b, z:3c}]

我的代码:


def add_entries(list_of_dict):
   keys = ['x','y','z']
   #defining a temporary dictionary here
   my_dict = dict.fromkeys(keys,0)
   entry_keys = ['ka','kb','kc']

   my_list = []

   for item in list_of_dict:
    # conditionally append the entries into the temporary dictionary maintaining desired key names
        my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
        my_list.append(my_dict)

   return my_list



if __name__ == "__main__":
   list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}]
   article_list = []
   returned_list = add_entries(list_of_dict)
   article_list.extend(returned_list)

我的输出

article_list = [{x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}]

【问题讨论】:

    标签: python python-3.x list dictionary append


    【解决方案1】:

    怎么了

    my_list.append(my_dict)reference 附加到my_dict 对象到my_list。因此,在您的示例中 for 循环的末尾,my_list 是对内存中完全相同的字典的引用列表。

    您可以使用函数id 亲自查看。 id,至少在 CPython 中,基本上是给你一个对象的内存地址。如果你这样做了

    article_list.extend(returned_list)
    print([id(d) for d in article_list])
    

    您将获得相同内存地址的列表。在我的机器上我得到了

    [139920570625792, 139920570625792, 139920570625792]
    

    结果是更新字典会影响列表中的“所有字典”。 (引用是因为您的列表中确实没有多个字典,只是完全相同的字典很多次)。所以最后,你只能看到最后一次更新操作。

    可以在这个答案https://stackoverflow.com/a/30340596/8791491中找到关于Python中引用和对象的很好的讨论

    修复

    my_dict 的定义移动到for 循环内,意味着您为my_list 的每个元素获得一个新的、单独的字典。现在,更新操作不会影响列表中的其他字典,my_list 是对几个不同字典的引用的列表。

    def add_entries(list_of_dict):
        keys = ['x','y','z']
        entry_keys = ['ka','kb','kc']
    
        my_list = []
    
        for item in list_of_dict:
            #defining a new dictionary here
            my_dict = dict.fromkeys(keys,0)
    
            # conditionally append the entries into the temporary dictionary maintaining desired key names
            my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
            my_list.append(my_dict)
    
        return my_list
    

    【讨论】:

      【解决方案2】:

      你可以用这个。

      keys=['x','y','z']
      res=[{k1:d[k]} for d in list_of_dict for k,k1 in zip(d,keys)]
      

      输出

      [{'x': '1a'},
       {'y': '1b'},
       {'z': '1c'},
       {'x': '2a'},
       {'x': '3a'},
       {'y': '3b'},
       {'z': '3c'}]
      

      【讨论】:

        【解决方案3】:

        试试这个:

        list_new_d=[]
        for d in list_of_dict:
          new_d={}
        
          for k,v in d.items():
            if k == 'ka':
              new_d['x'] = v
        
            if k == 'kb':
              new_d['y'] = v
        
            if k == 'kc':
              new_d['z'] = v
          list_new_d.append(new_d)
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-04
          • 1970-01-01
          • 2011-02-11
          • 1970-01-01
          • 1970-01-01
          • 2021-12-01
          • 2020-01-12
          • 1970-01-01
          相关资源
          最近更新 更多