从嵌套列表创建字典

Create dictionary from a nested list

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

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

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

dict = {1: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
  'SalePrice': 'Sale price.95',
  'Saving': '                Save 79%'},
 2: {'ItemName': 'Raji GlovesSixSixOneRegular price',
  'SalePrice': 'Sale price.95',
  'Saving': '                Save 79%'},
 3: {'ItemName': 'Shasta 3/4 Cycling Tights - WomensSpecializedRegular price',
  'SalePrice': 'Sale price.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

但是如何在不删除值的情况下将其添加到字典中呢?感谢您的帮助!

像这样:

from pprint import pprint


my_list = [['Raji GlovesSixSixOneRegular price',
  'Sale price.95',
  '                Save 67%'],
 ['Comp Vortex GlovesSixSixOneRegular price',
  'Sale price.95',
  '                Save 67%'],
 ["Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
  'Sale price.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.95',
     'Saving': '                Save 67%'},
 2: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
     'SalePrice': 'Sale price.95',
     'Saving': '                Save 67%'},
 3: {'ItemName': "Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
     'SalePrice': 'Sale price.95',
     'Saving': '                Save 79%'}}

注意:pprint 仅适用于 pretty 字典,您无需导入即可使代码本身正常工作。

解决方案是这样的:

  • 在外面,你得到了一个字典理解,把一个可迭代的元组变成了一个字典;一个更简单的例子是:
ts = [(1, 'one'), (2, 'two')]
d = {number: name for number, name in ts}
  • 它没有像那个例子那样传入一个元组列表,而是获取 enumerate() 函数的结果,该函数接受一个可迭代对象和 returns 一个将每个元素与一个配对的可迭代对象索引,例如:
# this prints [(0, 'a'), (1, 'b'), (2, 'c')]
print(list(enumerate(['a', 'b', 'c'])))
  • 您可以看到它如何为您提供填充字典所需的内容,只是它从 0 开始,所以这就是 n[=58 之后有一个 + 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)}

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

如果您想真正发疯,这是我的在线解决方案。很难描述...

enumerate 基本上 returns 我们为数组中的每个元素提供两个项目,第一个是索引号,第二个是真实对象。这样我们就可以就地计算它。然后我们将它指定为外部字典中的键,作为该键的值,我们将数组中的值插入到内部字典中。

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

from pprint import pprint

my_list = [['Raji GlovesSixSixOneRegular price',
  'Sale price.95',
  '                Save 67%'],
 ['Comp Vortex GlovesSixSixOneRegular price',
  'Sale price.95',
  '                Save 67%'],
 ["Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
  'Sale price.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.95',
     'Saving': 'Save 67%'},
 2: {'ItemName': 'Comp Vortex GlovesSixSixOneRegular price',
     'SalePrice': 'Sale price.95',
     'Saving': 'Save 67%'},
 3: {'ItemName': "Shasta 3/4 Cycling Tights - Women'sSpecializedRegular price",
     'SalePrice': 'Sale price.95',
     'Saving': 'Save 79%'}}