【问题标题】:Create dictionary from a nested list从嵌套列表创建字典
【发布时间】:2021-04-19 23:55:30
【问题描述】:

我有一个如下所示的嵌套列表:

my_list = [['Raji GlovesSixSixOneRegular price',
  'Sale price$9.95',
  '                Save 67%'],
 ['Comp Vortex GlovesSixSixOneRegular price',
  'Sale price$9.95',
  '                Save 67%'],
 ["Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
  'Sale price$14.95',
  '                Save 79%']]

我想创建一个嵌套字典,每个列表项中的第一个值是“ItemName”,第二个是“SalePrice”,第三个是“Saving”。像这样:

dict = {1: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
  'SalePrice': 'Sale price$9.95',
  'Saving': '                Save 79%'},
 2: {'ItemName': 'Raji GlovesSixSixOneRegular price',
  'SalePrice': 'Sale price$9.95',
  'Saving': '                Save 79%'},
 3: {'ItemName': 'Shasta 3/4 Cycling Tights - WomensSpecializedRegular price',
  'SalePrice': 'Sale price$14.95',
  'Saving': '                Save 79%'}}


keys = ('ItemName', 'SalePrice','Saving') 

如果我只是添加列表中的第一项,我知道我可以这样做:

values= my_list[0]
values
    
res = {} 
for key in keys: 
    for value in values: 
        res[key] = value 
        values.remove(value) 
        break  
res

但是如何在不删除值的情况下将其添加到字典中?任何帮助表示赞赏!

【问题讨论】:

    标签: python dictionary-comprehension


    【解决方案1】:

    类似这样的:

    from pprint import pprint
    
    
    my_list = [['Raji GlovesSixSixOneRegular price',
      'Sale price$9.95',
      '                Save 67%'],
     ['Comp Vortex GlovesSixSixOneRegular price',
      'Sale price$9.95',
      '                Save 67%'],
     ["Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
      'Sale price$14.95',
      '                Save 79%']]
    
    my_dict = {
        n + 1: d for n, d in enumerate(
            dict(zip(['ItemName', 'SalePrice', 'Saving'], item)) for item in my_list
        )
    }
    
    pprint(my_dict)
    

    结果:

    {1: {'ItemName': 'Raji GlovesSixSixOneRegular price',
         'SalePrice': 'Sale price$9.95',
         'Saving': '                Save 67%'},
     2: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
         'SalePrice': 'Sale price$9.95',
         'Saving': '                Save 67%'},
     3: {'ItemName': "Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
         'SalePrice': 'Sale price$14.95',
         'Saving': '                Save 79%'}}
    

    注意:pprint 仅用于漂亮的字典,您不需要导入即可使代码本身工作。

    解决方案如下:

    • 在外面,你得到一个字典理解,将一个可迭代的元组变成字典;一个更简单的例子是:
    ts = [(1, 'one'), (2, 'two')]
    d = {number: name for number, name in ts}
    
    • 不像在该示例中那样传入元组列表,而是获取 enumerate() 函数的结果,该函数接受一个可迭代对象并返回将每个元素与索引配对的可迭代对象,例如:
    # this prints [(0, 'a'), (1, 'b'), (2, 'c')]
    print(list(enumerate(['a', 'b', 'c'])))
    
    • 你可以看到它是如何得到你需要填写字典的,除了它从0开始,这就是为什么在n之后有一个+ 1
    • enumerate() 函数获取生成器表达式dict(<something>) for item in my_list) 的结果。枚举生成器表达式的示例:
    print(list(enumerate(n for n in range(10, 20))))
    
    • 生成器异常使用zip(),它采用两个可迭代对象并将结果配对,在这种情况下,您需要用于内部字典['ItemName', 'SalePrice', 'Saving'] 的键和原始列表中的列表,一一传递给它由生成器表达式。尝试运行这个:
    print(list(list(zip(['ItemName', 'SalePrice', 'Saving'], item)) for item in my_list))
    

    这应该让您对正在发生的事情有所了解。

    通常,如果您收到一些有效的代码,但您无法真正说出原因,请尝试查看表达式如何组合在一起。如果你真的把它分开,它看起来像这样:

    my_dict = {
        number + 1: dict_element 
        for number, dict_element  in enumerate(
            dict(
                zip(['ItemName', 'SalePrice', 'Saving'], item)
            ) 
            for item in my_list
        )
    }
    

    然后尝试如果您了解每一点,从内部部分开始。因此,在这种情况下,您需要弄清楚 zip() 的作用。玩弄这个函数,直到你理解它,然后再上一层,看看dict() 对zip() 函数的结果做了什么。一旦你明白了,看看为什么后面有一个for(它是一个生成器)等等。

    当然,如果您希望您的代码比其他任何东西都短,这也是一样的,但很难破译:

    d = {n+1: d for n, d in enumerate(dict(zip(['ItemName','SalePrice','Saving'], x)) for x in my_list)}
    

    感谢您要求解释,因为这意味着您正在努力学习,而不仅仅是复制答案 - 继续努力。

    【讨论】:

    • 谢谢你,介意在你的回答中解释它是如何工作的吗?我真的是 Python 新手!
    • 我希望添加的解释有帮助 - 我喜欢这个解决方案,因为它非常 Pythonic,在一个单一的、可读的(如果你扩展它)表达式中完成所有事情,这使得它可以轻松地作为更大的一部分重用表达式。这是一些程序员会告诉你不要使用for 循环的主要原因,尽管许多程序员会告诉你不要使用for 循环而不知道为什么。
    • 你写的是 enumerate 得到的是 zip 的结果,但实际上它是生成器的结果,其中 dict 应用于 zip?
    • @D.BenKnoble - 谢谢,很好,现在进行编辑。
    【解决方案2】:

    如果您想真正发疯,这是我的解决方案。很难形容……

    enumerate 基本上为数组中的每个元素返回两个项目,第一个是索引号,第二个是真实对象。这样我们就可以就地计算它。然后我们将其分配为外部字典中的键,并作为该键的值插入内部字典,其中包含数组中的值。

    我还使用了.strip 函数来删除不必要的空格等。

    from pprint import pprint
    
    my_list = [['Raji GlovesSixSixOneRegular price',
      'Sale price$9.95',
      '                Save 67%'],
     ['Comp Vortex GlovesSixSixOneRegular price',
      'Sale price$9.95',
      '                Save 67%'],
     ["Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
      'Sale price$14.95',
      '                Save 79%']]
    
    
    newDict = {i + 1: {"ItemName": arr[0].strip(), "SalePrice": arr[1].strip(), "Saving": arr[2].strip()} for i, arr in enumerate(my_list)}
    
    pprint(newDict)
    

    这里也是上述解决方案的基本等价物:

    newDict = {}
    for i, arr in enumerate(my_list):
        newDict[i + 1] = {}
        newDict[i + 1]["ItemName"] = arr[0]
        newDict[i + 1]["SalePrice"] = arr[1]
        newDict[i + 1]["Saving"] = arr[2]
    
    
    pprint(newDict)
    

    这是另一个简单的解决方案,这里我们定义一个字典并将起始数字定义为 1,迭代 my_list 数组,然后我们在该迭代中分配一个字典。在字典里面我们可以从arr对象中填写。

    i = 1
    newDict = {}
    for arr in my_list:
        newDict[i] = {
            "ItemName": arr[0].strip(),
            "SalePrice": arr[1].strip(),
            "Saving": arr[2].strip(),
        }
        i += 1
    

    输出

    {1: {'ItemName': 'Raji GlovesSixSixOneRegular price',
         'SalePrice': 'Sale price$9.95',
         'Saving': 'Save 67%'},
     2: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
         'SalePrice': 'Sale price$9.95',
         'Saving': 'Save 67%'},
     3: {'ItemName': "Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
         'SalePrice': 'Sale price$14.95',
         'Saving': 'Save 79%'}}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2021-11-20
      • 2018-01-16
      • 1970-01-01
      • 2020-10-22
      • 2021-09-15
      相关资源
      最近更新 更多