简体   繁体   English

从嵌套列表创建字典

[英]Create dictionary from a nested list

I have a nested list that looks like this:我有一个看起来像这样的嵌套列表:

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%']]

I would like to create a nested dictionary such that, the first value in each list item is the 'ItemName', the second is the 'SalePrice' and the third is the 'Saving'.我想创建一个嵌套字典,每个列表项中的第一个值是“ItemName”,第二个是“SalePrice”,第三个是“Saving”。 such like this:像这样:

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') 

I know I could do something like this, if I was just adding the first item in the list:我知道我可以做这样的事情,如果我只是添加列表中的第一项:

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

But how do I added it to the dictionary without removing values?但是如何在不删除值的情况下将其添加到字典中? Any help is appreciated!任何帮助表示赞赏!

Something like this:像这样的东西:

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)

Result:结果:

{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%'}}

Note: pprint is only there for the pretty dictionary, you don't need the import to make the code itself work.注意: pprint仅用于漂亮的字典,您不需要导入来使代码本身工作。

The solution works like this:该解决方案的工作原理如下:

  • on the outside, you get a dictionary comprehension, turning an iterable of tuples into a dictionary;在外面,你得到一个字典理解,将一个可迭代的元组变成字典; a simpler example is:一个更简单的例子是:
ts = [(1, 'one'), (2, 'two')]
d = {number: name for number, name in ts}
  • instead of passing in a list of tuples, like in that example, it gets the result of the enumerate() function, which takes an iterable and returns an iterable that pairs each element with an index, for example:它不是像在那个例子中那样传入一个元组列表,而是获取enumerate() function 的结果,它接受一个可迭代对象并返回一个将每个元素与索引配对的可迭代对象,例如:
# this prints [(0, 'a'), (1, 'b'), (2, 'c')]
print(list(enumerate(['a', 'b', 'c'])))
  • You can see how that gets you what you need to fill the dictionary, except that it starts at 0 , so that's why there's a + 1 after n您可以看到它如何为您提供填充字典所需的内容,除了它从0开始,这就是为什么在n之后有一个+ 1
  • The enumerate() function gets the result of a generator expression dict(<something>) for item in my_list) . enumerate() function 获取生成器表达式dict(<something>) for item in my_list)的结果。 An example of enumerating a generator expression:枚举生成器表达式的示例:
print(list(enumerate(n for n in range(10, 20))))
  • The generator exception uses zip() , which takes two iterables and pairs up the results, in this case the keys you want for your inner dictionaries ['ItemName', 'SalePrice', 'Saving'] and the lists in your original list, one by one, as handed to it by the generator expression.生成器异常使用zip() ,它接受两个可迭代对象并将结果配对,在这种情况下,您需要内部字典['ItemName', 'SalePrice', 'Saving']和原始列表中的列表的键,一个接一个,由生成器表达式传递给它。 Try running just this:尝试运行这个:
print(list(list(zip(['ItemName', 'SalePrice', 'Saving'], item)) for item in my_list))

That should give you some idea of what's going on.这应该让您对正在发生的事情有所了解。

Generally, if you receive a bit of code that works, but you can't really tell why, try to see how the expression fits together.通常,如果您收到一些有效的代码,但您无法真正说出原因,请尝试查看表达式如何组合在一起。 If you really tease it apart, it looks like this:如果你真的把它分开,它看起来像这样:

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

Then try if you understand each bit, starting with the inner parts.然后尝试如果您了解每一点,从内部部分开始。 So, in this case, you'd want to figure out what zip() does.因此,在这种情况下,您需要弄清楚zip()的作用。 Play around with the function, until you understand it, then go up a level, see what dict() does with the result of a zip() function.玩弄 function,直到你理解它,然后 go 更上一层楼,看看dict()zip() ZC1C425268E68385D1AB5074C17A94F1 的结果做了什么。 Once you get that, see why there's a for after it (it's a generator), etc.一旦你明白了,看看为什么它后面有一个for (它是一个生成器)等等。

Of course, if you prefer your code to be short above anything else, this is the same, but hard to decipher:当然,如果您希望您的代码比其他任何东西都短,这是相同的,但很难破译:

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

I appreciate you asking for an explanation, because it means you're trying to learn and not just copying answers - keep it up.感谢您要求解释,因为这意味着您正在尝试学习,而不仅仅是复制答案-继续努力。

If you wanna go real crazy, here is my solution in one line.如果你想 go 真的很疯狂,这是我的解决方案。 It's hard to describe...很难描述...

enumerate basically returns us two items for each element in array, first is the index number the second is the real object. enumerate基本上为数组中的每个元素返回两个项目,第一个是索引号,第二个是真正的 object。 That way we can count it in-place.这样我们就可以就地计算它。 Then we assign it as key in outer dict, and as the value of that key we insert the inner dictionary with values from the array.然后我们将它分配为外部字典中的键,并作为该键的值,我们插入带有数组值的内部字典。

I also used .strip function to remove unnecesary spaces etc.我还使用.strip function 来删除不必要的空格等。

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)

Also here is the basic equavilent of the solution above:这里也是上述解决方案的基本等价物:

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)

Here is another easy solution, here we define a dictionary and define a starting number as 1, iterating over the my_list array and then we assign a dictionary in that iteration.这是另一个简单的解决方案,这里我们定义一个字典并将起始编号定义为 1,迭代my_list数组,然后我们在该迭代中分配一个字典。 Inside the dictionary we can fill in from the arr object.在字典里面我们可以从arr object中填写。

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

Output Output

{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%'}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM