Converting list of lists into a dictionary of dictionaries in Python
Clash Royale CLAN TAG#URR8PPP
up vote
19
down vote
favorite
I am trying to convert a list of lists data structure to a dictionary of dictionaries.
The list is defined as follows:
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
My aim is to have the dictionary structure as follows:
#'PP' : 'Holesovice' : 'Ear-rings' : 2000, 'Skirts' : 1000,
# 'E-shop' : 'Dresses' : 1500,
# 'BM' : 'Holesovice' : 'Butterfly' : 1600
#
This bit of code does not return desired output:
labels_d =
items_d =
shops_d =
for index, row in enumerate(l):
items_d[row[1]] = row[3]
shops_d[row[2]] = items_d
labels_d[row[0]] = shops_d
print(labels_d)
I found some posts that deal with converting lists to dictionaries here and here but I did not make it work the way I want. Is there any 'clean' way how to achieve the structure posted above?
python python-3.x list dictionary nested
add a comment |Â
up vote
19
down vote
favorite
I am trying to convert a list of lists data structure to a dictionary of dictionaries.
The list is defined as follows:
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
My aim is to have the dictionary structure as follows:
#'PP' : 'Holesovice' : 'Ear-rings' : 2000, 'Skirts' : 1000,
# 'E-shop' : 'Dresses' : 1500,
# 'BM' : 'Holesovice' : 'Butterfly' : 1600
#
This bit of code does not return desired output:
labels_d =
items_d =
shops_d =
for index, row in enumerate(l):
items_d[row[1]] = row[3]
shops_d[row[2]] = items_d
labels_d[row[0]] = shops_d
print(labels_d)
I found some posts that deal with converting lists to dictionaries here and here but I did not make it work the way I want. Is there any 'clean' way how to achieve the structure posted above?
python python-3.x list dictionary nested
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08
add a comment |Â
up vote
19
down vote
favorite
up vote
19
down vote
favorite
I am trying to convert a list of lists data structure to a dictionary of dictionaries.
The list is defined as follows:
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
My aim is to have the dictionary structure as follows:
#'PP' : 'Holesovice' : 'Ear-rings' : 2000, 'Skirts' : 1000,
# 'E-shop' : 'Dresses' : 1500,
# 'BM' : 'Holesovice' : 'Butterfly' : 1600
#
This bit of code does not return desired output:
labels_d =
items_d =
shops_d =
for index, row in enumerate(l):
items_d[row[1]] = row[3]
shops_d[row[2]] = items_d
labels_d[row[0]] = shops_d
print(labels_d)
I found some posts that deal with converting lists to dictionaries here and here but I did not make it work the way I want. Is there any 'clean' way how to achieve the structure posted above?
python python-3.x list dictionary nested
I am trying to convert a list of lists data structure to a dictionary of dictionaries.
The list is defined as follows:
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
My aim is to have the dictionary structure as follows:
#'PP' : 'Holesovice' : 'Ear-rings' : 2000, 'Skirts' : 1000,
# 'E-shop' : 'Dresses' : 1500,
# 'BM' : 'Holesovice' : 'Butterfly' : 1600
#
This bit of code does not return desired output:
labels_d =
items_d =
shops_d =
for index, row in enumerate(l):
items_d[row[1]] = row[3]
shops_d[row[2]] = items_d
labels_d[row[0]] = shops_d
print(labels_d)
I found some posts that deal with converting lists to dictionaries here and here but I did not make it work the way I want. Is there any 'clean' way how to achieve the structure posted above?
python python-3.x list dictionary nested
python python-3.x list dictionary nested
edited Sep 5 at 17:50
jpp
66.7k173983
66.7k173983
asked Sep 5 at 13:55
New2Python
17011
17011
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08
add a comment |Â
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
24
down vote
accepted
Using dict.setdefault(key, )
is a good way to approach the creation of nested dictionaries of fixed depth.
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
d =
for tag, item, source, qty in l:
d.setdefault(tag, ).setdefault(source, )[item] = qty
Output
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Generalization
The above solution can be made more general by building a class of nested dictionary, dropping the requirements to have a fixed depth.
class NestedDict(dict):
def __getitem__(self, item):
if item not in self:
self[item] = NestedDict()
return super().__getitem__(item)
d = NestedDict()
for tag, item, source, qty in l:
d[tag][source][item] = qty
Also notice that the class approach is created so it only creates an object if the key does not exist while the setdefault
approach created an empty dict
on every access.
4
It really grinds something in the back of my head to see a new object created every time you callsetdefault
, although this is a very nice solution.
â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean thatNestedDict()
is called whether or notitem
already has a value, which is a little inelegant.
â Patrick Haugh
Sep 5 at 14:47
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction withsetdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.
â Mad Physicist
Sep 5 at 18:47
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
 |Â
show 1 more comment
up vote
17
down vote
You can use the infinitely nested defaultdict
trick:
from collections import defaultdict
def nested_dict():
return defaultdict(nested_dict)
nd = nested_dict()
for a, b, c, d in l:
nd[a][c][b] = d
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to thedefaultdict
constructor is the default factory ;-)
â schwobaseggl
Sep 5 at 14:25
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a keynd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary, while in my solution you get
0
. It may be relevant as conceptually you may not expect.
â jpp
Sep 5 at 16:10
 |Â
show 1 more comment
up vote
6
down vote
You can use collections.defaultdict
and iterate. In this case, you can define precisely a nested dictionary to reflect your data structure.
from collections import defaultdict
L = [['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]]
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
for code, item, shop, value in L:
d[code][shop][item] = value
Result
defaultdict('BM': defaultdict('Holesovice': defaultdict(int, 'Butterfly': 1600)),
'PP': defaultdict('E-shop': defaultdict(int, 'Dresses': 1500),
'Holesovice': defaultdict(int,
'Ear-rings': 2000, 'Skirts': 1000)))
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
add a comment |Â
up vote
0
down vote
def toNested1(l):
def addKeyDict(map,key):
if key not in map:
item = map[key] =
return item
return map[key]
zz =
for a0,a1,a2,a3 in l :
addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3
return zz
add a comment |Â
up vote
0
down vote
Here post a pretty straightforward way to compose a new dictionary:
If the items in each row of list not in the corresponding depth of dictionary, just add/append the key-value pair to the dict.
code:
list = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
dicta =
for row in list:
if row[0] not in dicta.keys():
dicta[row[0]] = row[2]:row[1]:row[3]
continue
if row[2] not in dicta[row[0]].keys():
dicta[row[0]][row[2]] = row[1]:row[3]
continue
if row[1] not in dicta[row[0]][row[2]].keys():
dicta[row[0]][row[2]][row[1]] = row[3]
print(dicta)
output:
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
24
down vote
accepted
Using dict.setdefault(key, )
is a good way to approach the creation of nested dictionaries of fixed depth.
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
d =
for tag, item, source, qty in l:
d.setdefault(tag, ).setdefault(source, )[item] = qty
Output
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Generalization
The above solution can be made more general by building a class of nested dictionary, dropping the requirements to have a fixed depth.
class NestedDict(dict):
def __getitem__(self, item):
if item not in self:
self[item] = NestedDict()
return super().__getitem__(item)
d = NestedDict()
for tag, item, source, qty in l:
d[tag][source][item] = qty
Also notice that the class approach is created so it only creates an object if the key does not exist while the setdefault
approach created an empty dict
on every access.
4
It really grinds something in the back of my head to see a new object created every time you callsetdefault
, although this is a very nice solution.
â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean thatNestedDict()
is called whether or notitem
already has a value, which is a little inelegant.
â Patrick Haugh
Sep 5 at 14:47
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction withsetdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.
â Mad Physicist
Sep 5 at 18:47
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
 |Â
show 1 more comment
up vote
24
down vote
accepted
Using dict.setdefault(key, )
is a good way to approach the creation of nested dictionaries of fixed depth.
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
d =
for tag, item, source, qty in l:
d.setdefault(tag, ).setdefault(source, )[item] = qty
Output
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Generalization
The above solution can be made more general by building a class of nested dictionary, dropping the requirements to have a fixed depth.
class NestedDict(dict):
def __getitem__(self, item):
if item not in self:
self[item] = NestedDict()
return super().__getitem__(item)
d = NestedDict()
for tag, item, source, qty in l:
d[tag][source][item] = qty
Also notice that the class approach is created so it only creates an object if the key does not exist while the setdefault
approach created an empty dict
on every access.
4
It really grinds something in the back of my head to see a new object created every time you callsetdefault
, although this is a very nice solution.
â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean thatNestedDict()
is called whether or notitem
already has a value, which is a little inelegant.
â Patrick Haugh
Sep 5 at 14:47
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction withsetdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.
â Mad Physicist
Sep 5 at 18:47
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
 |Â
show 1 more comment
up vote
24
down vote
accepted
up vote
24
down vote
accepted
Using dict.setdefault(key, )
is a good way to approach the creation of nested dictionaries of fixed depth.
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
d =
for tag, item, source, qty in l:
d.setdefault(tag, ).setdefault(source, )[item] = qty
Output
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Generalization
The above solution can be made more general by building a class of nested dictionary, dropping the requirements to have a fixed depth.
class NestedDict(dict):
def __getitem__(self, item):
if item not in self:
self[item] = NestedDict()
return super().__getitem__(item)
d = NestedDict()
for tag, item, source, qty in l:
d[tag][source][item] = qty
Also notice that the class approach is created so it only creates an object if the key does not exist while the setdefault
approach created an empty dict
on every access.
Using dict.setdefault(key, )
is a good way to approach the creation of nested dictionaries of fixed depth.
l = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
d =
for tag, item, source, qty in l:
d.setdefault(tag, ).setdefault(source, )[item] = qty
Output
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Generalization
The above solution can be made more general by building a class of nested dictionary, dropping the requirements to have a fixed depth.
class NestedDict(dict):
def __getitem__(self, item):
if item not in self:
self[item] = NestedDict()
return super().__getitem__(item)
d = NestedDict()
for tag, item, source, qty in l:
d[tag][source][item] = qty
Also notice that the class approach is created so it only creates an object if the key does not exist while the setdefault
approach created an empty dict
on every access.
edited Sep 8 at 13:38
answered Sep 5 at 14:01
Olivier Melançon
11.8k11436
11.8k11436
4
It really grinds something in the back of my head to see a new object created every time you callsetdefault
, although this is a very nice solution.
â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean thatNestedDict()
is called whether or notitem
already has a value, which is a little inelegant.
â Patrick Haugh
Sep 5 at 14:47
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction withsetdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.
â Mad Physicist
Sep 5 at 18:47
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
 |Â
show 1 more comment
4
It really grinds something in the back of my head to see a new object created every time you callsetdefault
, although this is a very nice solution.
â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean thatNestedDict()
is called whether or notitem
already has a value, which is a little inelegant.
â Patrick Haugh
Sep 5 at 14:47
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction withsetdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.
â Mad Physicist
Sep 5 at 18:47
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
4
4
It really grinds something in the back of my head to see a new object created every time you call
setdefault
, although this is a very nice solution.â Mad Physicist
Sep 5 at 14:09
It really grinds something in the back of my head to see a new object created every time you call
setdefault
, although this is a very nice solution.â Mad Physicist
Sep 5 at 14:09
@OlivierMelançon They just mean that
NestedDict()
is called whether or not item
already has a value, which is a little inelegant.â Patrick Haugh
Sep 5 at 14:47
@OlivierMelançon They just mean that
NestedDict()
is called whether or not item
already has a value, which is a little inelegant.â Patrick Haugh
Sep 5 at 14:47
1
1
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
@MadPhysicist this is solved in the general approach
â Olivier Melançon
Sep 5 at 15:47
1
1
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction with
setdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.â Mad Physicist
Sep 5 at 18:47
I'm aware of the solution and I'm sure you are too. I liked your original answer for it's simplicity. My comment was just a general dissatisfaction with
setdefault
. It would be nice to have another method that accepts a callable instead of a preconstructed instance.â Mad Physicist
Sep 5 at 18:47
1
1
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
I've never posted anything on the Python discussion thread before. Maybe now would be a good time to start. I'll see if I can come up with a simple implementation first.
â Mad Physicist
Sep 6 at 2:08
 |Â
show 1 more comment
up vote
17
down vote
You can use the infinitely nested defaultdict
trick:
from collections import defaultdict
def nested_dict():
return defaultdict(nested_dict)
nd = nested_dict()
for a, b, c, d in l:
nd[a][c][b] = d
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to thedefaultdict
constructor is the default factory ;-)
â schwobaseggl
Sep 5 at 14:25
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a keynd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary, while in my solution you get
0
. It may be relevant as conceptually you may not expect.
â jpp
Sep 5 at 16:10
 |Â
show 1 more comment
up vote
17
down vote
You can use the infinitely nested defaultdict
trick:
from collections import defaultdict
def nested_dict():
return defaultdict(nested_dict)
nd = nested_dict()
for a, b, c, d in l:
nd[a][c][b] = d
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to thedefaultdict
constructor is the default factory ;-)
â schwobaseggl
Sep 5 at 14:25
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a keynd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary, while in my solution you get
0
. It may be relevant as conceptually you may not expect.
â jpp
Sep 5 at 16:10
 |Â
show 1 more comment
up vote
17
down vote
up vote
17
down vote
You can use the infinitely nested defaultdict
trick:
from collections import defaultdict
def nested_dict():
return defaultdict(nested_dict)
nd = nested_dict()
for a, b, c, d in l:
nd[a][c][b] = d
You can use the infinitely nested defaultdict
trick:
from collections import defaultdict
def nested_dict():
return defaultdict(nested_dict)
nd = nested_dict()
for a, b, c, d in l:
nd[a][c][b] = d
edited Sep 5 at 14:22
answered Sep 5 at 14:00
schwobaseggl
31k31835
31k31835
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to thedefaultdict
constructor is the default factory ;-)
â schwobaseggl
Sep 5 at 14:25
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a keynd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary, while in my solution you get
0
. It may be relevant as conceptually you may not expect.
â jpp
Sep 5 at 16:10
 |Â
show 1 more comment
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to thedefaultdict
constructor is the default factory ;-)
â schwobaseggl
Sep 5 at 14:25
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a keynd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary, while in my solution you get
0
. It may be relevant as conceptually you may not expect.
â jpp
Sep 5 at 16:10
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
I love this as well. I feel it would be somewhat neater if you made nested_dict a class instead of a factory.
â Olivier Melançon
Sep 5 at 14:14
1
1
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to the
defaultdict
constructor is the default factory ;-)â schwobaseggl
Sep 5 at 14:25
@OlivierMelançon Certainly a challenge to have the recursive logic in a class in such a tidy way. After all, the argument to the
defaultdict
constructor is the default factory ;-)â schwobaseggl
Sep 5 at 14:25
1
1
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.
class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@schwobaseggl it's fairly simple really since the factory is stored as an instance argument.
class NestedDict(defaultdict): def __init__(self): self.default_factory = NestedDict
â Olivier Melançon
Sep 5 at 14:29
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
@OlivierMelançon True, I like that as well. It certainly provides an additional insight.
â schwobaseggl
Sep 5 at 14:35
1
1
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a key
nd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary
, while in my solution you get 0
. It may be relevant as conceptually you may not expect
.â jpp
Sep 5 at 16:10
This answer is, of course, good. BUT I do think it's important to note the difference between this and my very similar but more precise answer. When you check a key
nd['key1']['key2']['key3']
and it doesn't exist you will get an empty dictionary
, while in my solution you get 0
. It may be relevant as conceptually you may not expect
.â jpp
Sep 5 at 16:10
 |Â
show 1 more comment
up vote
6
down vote
You can use collections.defaultdict
and iterate. In this case, you can define precisely a nested dictionary to reflect your data structure.
from collections import defaultdict
L = [['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]]
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
for code, item, shop, value in L:
d[code][shop][item] = value
Result
defaultdict('BM': defaultdict('Holesovice': defaultdict(int, 'Butterfly': 1600)),
'PP': defaultdict('E-shop': defaultdict(int, 'Dresses': 1500),
'Holesovice': defaultdict(int,
'Ear-rings': 2000, 'Skirts': 1000)))
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
add a comment |Â
up vote
6
down vote
You can use collections.defaultdict
and iterate. In this case, you can define precisely a nested dictionary to reflect your data structure.
from collections import defaultdict
L = [['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]]
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
for code, item, shop, value in L:
d[code][shop][item] = value
Result
defaultdict('BM': defaultdict('Holesovice': defaultdict(int, 'Butterfly': 1600)),
'PP': defaultdict('E-shop': defaultdict(int, 'Dresses': 1500),
'Holesovice': defaultdict(int,
'Ear-rings': 2000, 'Skirts': 1000)))
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
add a comment |Â
up vote
6
down vote
up vote
6
down vote
You can use collections.defaultdict
and iterate. In this case, you can define precisely a nested dictionary to reflect your data structure.
from collections import defaultdict
L = [['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]]
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
for code, item, shop, value in L:
d[code][shop][item] = value
Result
defaultdict('BM': defaultdict('Holesovice': defaultdict(int, 'Butterfly': 1600)),
'PP': defaultdict('E-shop': defaultdict(int, 'Dresses': 1500),
'Holesovice': defaultdict(int,
'Ear-rings': 2000, 'Skirts': 1000)))
You can use collections.defaultdict
and iterate. In this case, you can define precisely a nested dictionary to reflect your data structure.
from collections import defaultdict
L = [['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]]
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
for code, item, shop, value in L:
d[code][shop][item] = value
Result
defaultdict('BM': defaultdict('Holesovice': defaultdict(int, 'Butterfly': 1600)),
'PP': defaultdict('E-shop': defaultdict(int, 'Dresses': 1500),
'Holesovice': defaultdict(int,
'Ear-rings': 2000, 'Skirts': 1000)))
answered Sep 5 at 14:01
jpp
66.7k173983
66.7k173983
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
add a comment |Â
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
It took me a while to notice it, but returning 0 at the bottom of the dict is both subtle and neat
â Olivier Melançon
Sep 5 at 17:39
add a comment |Â
up vote
0
down vote
def toNested1(l):
def addKeyDict(map,key):
if key not in map:
item = map[key] =
return item
return map[key]
zz =
for a0,a1,a2,a3 in l :
addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3
return zz
add a comment |Â
up vote
0
down vote
def toNested1(l):
def addKeyDict(map,key):
if key not in map:
item = map[key] =
return item
return map[key]
zz =
for a0,a1,a2,a3 in l :
addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3
return zz
add a comment |Â
up vote
0
down vote
up vote
0
down vote
def toNested1(l):
def addKeyDict(map,key):
if key not in map:
item = map[key] =
return item
return map[key]
zz =
for a0,a1,a2,a3 in l :
addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3
return zz
def toNested1(l):
def addKeyDict(map,key):
if key not in map:
item = map[key] =
return item
return map[key]
zz =
for a0,a1,a2,a3 in l :
addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3
return zz
answered Sep 5 at 15:17
napuzba
3,21231021
3,21231021
add a comment |Â
add a comment |Â
up vote
0
down vote
Here post a pretty straightforward way to compose a new dictionary:
If the items in each row of list not in the corresponding depth of dictionary, just add/append the key-value pair to the dict.
code:
list = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
dicta =
for row in list:
if row[0] not in dicta.keys():
dicta[row[0]] = row[2]:row[1]:row[3]
continue
if row[2] not in dicta[row[0]].keys():
dicta[row[0]][row[2]] = row[1]:row[3]
continue
if row[1] not in dicta[row[0]][row[2]].keys():
dicta[row[0]][row[2]][row[1]] = row[3]
print(dicta)
output:
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
add a comment |Â
up vote
0
down vote
Here post a pretty straightforward way to compose a new dictionary:
If the items in each row of list not in the corresponding depth of dictionary, just add/append the key-value pair to the dict.
code:
list = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
dicta =
for row in list:
if row[0] not in dicta.keys():
dicta[row[0]] = row[2]:row[1]:row[3]
continue
if row[2] not in dicta[row[0]].keys():
dicta[row[0]][row[2]] = row[1]:row[3]
continue
if row[1] not in dicta[row[0]][row[2]].keys():
dicta[row[0]][row[2]][row[1]] = row[3]
print(dicta)
output:
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Here post a pretty straightforward way to compose a new dictionary:
If the items in each row of list not in the corresponding depth of dictionary, just add/append the key-value pair to the dict.
code:
list = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
dicta =
for row in list:
if row[0] not in dicta.keys():
dicta[row[0]] = row[2]:row[1]:row[3]
continue
if row[2] not in dicta[row[0]].keys():
dicta[row[0]][row[2]] = row[1]:row[3]
continue
if row[1] not in dicta[row[0]][row[2]].keys():
dicta[row[0]][row[2]][row[1]] = row[3]
print(dicta)
output:
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
Here post a pretty straightforward way to compose a new dictionary:
If the items in each row of list not in the corresponding depth of dictionary, just add/append the key-value pair to the dict.
code:
list = [
['PP','Ear-rings', 'Holesovice', 2000],
['PP','Skirts', 'Holesovice', 1000],
['PP','Dresses', 'E-shop', 1500],
['BM','Butterfly', 'Holesovice', 1600]
]
dicta =
for row in list:
if row[0] not in dicta.keys():
dicta[row[0]] = row[2]:row[1]:row[3]
continue
if row[2] not in dicta[row[0]].keys():
dicta[row[0]][row[2]] = row[1]:row[3]
continue
if row[1] not in dicta[row[0]][row[2]].keys():
dicta[row[0]][row[2]][row[1]] = row[3]
print(dicta)
output:
'BM': 'Holesovice': 'Butterfly': 1600,
'PP': 'E-shop': 'Dresses': 1500,
'Holesovice': 'Ear-rings': 2000, 'Skirts': 1000
answered Sep 7 at 7:02
josephzhong
11
11
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52186918%2fconverting-list-of-lists-into-a-dictionary-of-dictionaries-in-python%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
If you found some posts then surely you must have tried something, even if it broke?
â Mad Physicist
Sep 5 at 13:58
stackoverflow.com/q/43234439/2988730
â Mad Physicist
Sep 5 at 14:08