【问题标题】:How is it possible to merge dictionaries with the same keys while renaming the keys?如何在重命名键时合并具有相同键的字典?
【发布时间】:2020-10-08 14:21:24
【问题描述】:

我正在做一个项目,我的情况是有多个字典,它们都包含相同的长度并且也填充了相同的键,每个值都是不同的灰度图片,所以是一个数组。

d1 = {'1' : 'a1' , '2' : 'a2' , '3' : 'a3'} 
d2 = {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'} 
d3 = {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}

你知道如何使用这些字典并构建一个包含所有图片但键从 1 开始到 n 结束的大字典,n 是图片的数量?图片的顺序无关紧要。

像这样:

d_new = { ' 1 ' : ' a1 ' , ' 2 ' : ' a2 ' , ' 3 ' : ' a3 ' , ' 4 ' : ' b1 ' , ' 5 ' : ' b2 ' , ' 6 ' : ' b3 ' , ' 7 ' : ' c1 ' , ' 8 ' : ' c2 ' , ' 9 ' : ' c3 ' }

因为键是相同的,所以当我合并它们时,我只得到一个长度为一个字典的字典。也不可能手动更改键的名称,然后合并字典,因为字典的数量取决于用户输入,范围从创建的 1 到 104400 个字典。

我还尝试使用嵌套字典,在尝试访问图片时出现“不可哈希”错误。

是否有一个简单的方法可以解决我遗漏的问题?

提前致谢:)。

干杯

编辑:谢谢你们,你们的大多数解决方案都很有魅力:)

【问题讨论】:

  • 将键从字符串更改为数字是否重要?目前,您将 '1' '2' 等作为字符串而不是实际数字。你也在 Python 3.6+ 上,如果是的话:项目字典条目是否保证是有序的?如果它们是,您可以按顺序遍历每个字典,并在程序上从 1 开始创建新的数字键。(我想您可以将str() 粘贴在它周围并再次返回字符串)如何提供输入字典?作为一个列表?

标签: python dictionary merge key


【解决方案1】:

借助itertools的力量!

使用字符串键:

>>> from itertools import chain, count
>>> dicts = [d1, d2, d3]
>>> dict(zip(map(str, count(1)), chain.from_iterable((d.values() for d in dicts))))
{'1': 'a1', '2': 'a2', '3': 'a3', '4': 'b1', '5': 'b2', '6': 'b3', '7': 'c1', '8': 'c2', '9': 'c3'}

使用 int 键:

>>> dict(zip(count(1), chain.from_iterable((d.values() for d in dicts))))
{1: 'a1', 2: 'a2', 3: 'a3', 4: 'b1', 5: 'b2', 6: 'b3', 7: 'c1', 8: 'c2', 9: 'c3'}

虽然后者有点无意义,因为您可以只使用一个列表,将索引从零开始。

请记住,您需要 Python 3.7 或更高版本才能获得确定性排序的 dicts。

【讨论】:

    【解决方案2】:

    假设所有my comment 都是这种情况,您可以将输入字典作为列表获取。你提到你有从 1 到 104400 的任意数量的输入字典,它们代表图像,所以我不会假设你的输入除了它是任意长度的字典列表之外的任何内容。

    我假设您已经可以将您的用户输入放入一个列表中,我们将这个字典列表称为 d_list

    >>>print(d_list)
    >>>[{'1' : 'a1' , '2' : 'a2' , '3' : 'a3'}, {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'}, {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}]
    

    那么,

    i = 1  # we're starting counting at 1
    d_new = {}
    for orig_dict in d_list:
        for val in orig_dict.values():
            d_new[str(i)] = val  # str() as originals had string keys
            i += 1
    

    这应该可以工作,因为 Python 3.6+ 字典是 ordered,也就是说,它们会记住添加项目的顺序。所以我们可以或多或少的把dict.values()当作一个列表。

    这应该给出您在问题中要求的确切输出。

    【讨论】:

      【解决方案3】:
      d1 = {'1' : 'a1' , '2' : 'a2' , '3' : 'a3'}
      d2 = {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'}
      d3 = {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}
      
      new_dict = {}
      key=1
      for old_dict in [d1, d2, d3]:
      
          for v in old_dict.values():
              new_dict[key] = v
              key += 1
      

      【讨论】:

      • 问题中的示例输出使用字符串作为键。为了匹配这一点,您可以在分配字典元素时转换为字符串。编辑:我现在看到有人对有关上述问题的问题添加了评论,所以最好在更改任何内容之前等待 OP 的回复。
      【解决方案4】:

      使用itertools.chain() 覆盖值并使用enumerate 作为新键的序列:

      
      from itertools import chain
      
      
      d1 = {'1' : 'a1' , '2' : 'a2' , '3' : 'a3'}
      d2 = {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'}
      d3 = {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}
      
      
      def dict_merge(*dicts):
          return {str(k): v for k, v in enumerate(chain.from_iterable(d.values() for d in dicts), start=1)}
      
      
      print(dict_merge(d1, d2, d3))
      

      输出:

      {'1': 'a1', '2': 'a2', '3': 'a3', '4': 'b1', '5': 'b2', '6': 'b3', '7': 'c1', '8': 'c2', '9': 'c3'}
      

      【讨论】:

        【解决方案5】:
        from itertools import chain
        print({str(k+1):v for (k,v) in enumerate(chain.from_iterable([d.values() for d in [d1,d2,d3] ]))})
        
        {'1': 'a1', '2': 'a2', '3': 'a3', '4': 'b1', '5': 'b2', '6': 'b3', '7': 'c1', '8': 'c2', '9': 'c3'}
        

        【讨论】:

          【解决方案6】:

          方法如下:

          d1 = {'1' : 'a1' , '2' : 'a2' , '3' : 'a3'}
          
          d2 = {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'}
          
          d3 = {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}
          
          l = [d1, d2, d3]
          
          d_new = {}
          
          i = 1
          
          for d in l:
              for k in d.keys():
                  d_new[str(i)] = d[k]
                  i += 1
          
          print(d_new)
          

          输出:

          {'1': 'a1', '2': 'a2', '3': 'a3', '4': 'b1', '5': 'b2', '6': 'b3', '7': 'c1', '8': 'c2', '9': 'c3'}
          

          如果字符串需要两边加空格:

          d1 = {'1' : 'a1' , '2' : 'a2' , '3' : 'a3'}
          
          d2 = {'1' : 'b1' , '2' : 'b2' , '3' : 'b3'}
          
          d3 = {'1' : 'c1' , '2' : 'c2' , '3' : 'c3'}
          
          l = [d1, d2, d3]
          
          d_new = {}
          
          i = 1
          
          for d in l:
              for k in d.keys():
                  d_new[f" {i} "] = f" {d[k]} "
                  i += 1
          
          print(d_new)
          

          输出:

          {' 1 ': ' a1 ', ' 2 ': ' a2 ', ' 3 ': ' a3 ', ' 4 ': ' b1 ', ' 5 ': ' b2 ', ' 6 ': ' b3 ', ' 7 ': ' c1 ', ' 8 ': ' c2 ', ' 9 ': ' c3 '}
          

          【讨论】:

          • 是的,谢谢,这正是我正在寻找的!
          猜你喜欢
          • 2013-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-16
          • 2023-03-30
          • 2019-11-19
          • 1970-01-01
          相关资源
          最近更新 更多