【问题标题】:Creating a nested dictionaries via for-loop通过 for 循环创建嵌套字典
【发布时间】:2022-01-03 19:18:15
【问题描述】:

我在使用 for 循环在另一个字典中创建具有多个键和值的字典时遇到问题。

我有一个程序可以读取另一个文本文件,然后将其信息输入字典。该文件如下所示:

GPU;GeForce GTX 1070 Ti;430
CPU;AMD Ryzen 7 2700X;233
GPU;GeForce GTX 2060;400
CPU;Intel Core i7-11700;360
RAM;HyperX 16GB;180
PSU;Corsair RM850X;210

我想要实现的是,我正在尝试为每个组件类型 {GPU、CPU、RAM、PSU 等}创建一个字典,并为那些我尝试输入另一个字典的组件创建一个字典,其中包括来自多个键和值,它们是 {name1 : price1, name2 : price2 等} 运行程序后,完整的字典应该是这样的:

"GPU": {"GeForce GTX 1070 Ti": 430, "GeForce GTX 2060 2": 233},
"CPU": {"AMD Ryzen 7 2700X": 233, "Intel Core i7-11700 : 360},
"RAM": {"HyperX 16GB": 180},
"PSU": {"Corsair RM850X": 210}

但是,它看起来像这样:

"GPU": {"GeForce GTX 2060 2": 233},
"CPU": {"Intel Core i7-11700 : 360},
"RAM": {"HyperX 16GB": 180},
"PSU": {"Corsair RM850X": 210}

问题出在这里:我无法正确创建字典,因为新的内部键和值会相互覆盖。我怎样才能让这个循环不这样做,而只是在内部字典中一个接一个地添加新值?

这是我的代码:

def main():
    filename = input("Enter the component file name: ")
    file = open(filename, mode="r")

    # Defining the outer dict. This dict's keys are the component types and
    # it's values are inner dictionaries.
    outer_dict = {}

    for row in file:
        row = row.strip()
        parts = row.split(";")

        # Defining variables for each part per line.
        type = parts[0]
        name = parts[1]
        price = int(parts[2])

        # Defining the inner dict. This dict's keys are the component's name
        # and it's price. There can be multiple names and prices in this dict.
        inner_dict = {}

        # Adding each name and price to the inner dictionaries.
        for i in range(1, len(parts)):
            inner_dict[name] = price

        # Adding the created inner dict into the outer dictionary.
        outer_dict[type] = inner_dict

    file.close()

if __name__ == "__main__":
    main()

提前感谢大家的帮助。真的很需要!

【问题讨论】:

  • 您似乎正在替换特定键的字典。在 for 循环结束时将内部 dict 添加到 outer_dict 时使用 update 方法。
  • 哦该死的,我不得不完全忘记使用这个更新功能。这解决了我的问题,而无需使用任何内置函数。谢谢!

标签: python dictionary data-structures nested filereader


【解决方案1】:

就是这个部分。您正在替换字典键的值。

outer_dict[type] = inner_dict

改为添加一个像这样的新子键

type = parts[0]
name = parts[1]
price = int(parts[2])
outer_dict[type][name] = price  # add `name` to the `type` dict as a new key

【讨论】:

    【解决方案2】:

    您可以使用collections.defaultdict 和一个简单的循环简单地实现预期的行为。

    注意。我在这里模拟一个带有拆分文本的文件

    f = '''GPU;GeForce GTX 1070 Ti;430
    CPU;AMD Ryzen 7 2700X;233
    GPU;GeForce GTX 2060;400
    CPU;Intel Core i7-11700;360
    RAM;HyperX 16GB;180
    PSU;Corsair RM850X;210'''
    
    from collections import defaultdict
    
    out = defaultdict(dict)
    
    for line in f.split('\n'):
        typ,name,price = line.split(';')
        out[typ][name] = price
    
    dict(out)
    

    输出:

    >>> dict(out)
    {'GPU': {'GeForce GTX 1070 Ti': '430', 'GeForce GTX 2060': '400'},
     'CPU': {'AMD Ryzen 7 2700X': '233', 'Intel Core i7-11700': '360'},
     'RAM': {'HyperX 16GB': '180'},
     'PSU': {'Corsair RM850X': '210'}}
    
    有一个文件:
    with open('file.txt') as f:
        for line in f:
            # rest of the loop from above
    

    【讨论】:

    • 注意你也可以用io.StringIO模拟文件
    • @Stef 我知道 ;) 但您不能将 StringIO 与 with 语句一起使用,因为 IO 对象已经“打开”
    【解决方案3】:

    对于outer_dict,您可以使用collections 中的defaultdict,将{} 设为默认值。这样你就可以简单地为每一行做outer_dict[type][name] = price

    【讨论】:

      【解决方案4】:

      感谢大家的帮助。我忘了提到,我不允许使用内置函数,但你的建议仍然是信息性的,可能对其他在 samillair 问题上苦苦挣扎的人有用。 通过使用更新方法,我得到了代码以一种想要的方式工作,建议:TheFlyingObject

      这是固定的内部 for 循环,其工作方式与预期相同:

              inner_dict = {}
      
              # Adding each name and price to the inner dictionaries.
              for i in range(1, len(parts)):
                  inner_dict[name] = price
      
              # Adding the created inner dict into the outer dictionary if it's
              # not already there.
              if type not in outer_dict:
                  outer_dict[type] = inner_dict
      
              # If there is already an outer dict existing, updating the inner dict.
              else:
                  outer_dict[type].update(inner_dict)
      

      【讨论】:

        猜你喜欢
        • 2021-07-25
        • 2019-03-29
        • 1970-01-01
        • 2020-11-02
        • 2019-09-30
        • 2020-09-13
        • 1970-01-01
        • 2020-06-14
        • 2021-12-03
        相关资源
        最近更新 更多