I have a list of dictionaries with info in such format:
p_mat_list = [
{'name': 'Mirror', 'link': '/somelink1/'},
{'name': 'Gold Leaf', 'link': '/somelink2/'}
]
First, create python list with all name values:
product_materials = []
for material in p_mat_list:
product_materials.append(material['name'])
However, I don't know what would be best way to get all name values when list will have nested list(s) with dictionaries alongside, as below:
p_mat_list = [
[{'name': 'Painted'}, {'name': 'Wood'}],
{'name': 'Mirror'},
{'name': 'Gold Leaf'}
]
How can I get all these name values: Painted
, Wood
, Mirror
, Gold Leaf
?
Also, how could I approach merging name values from all dictionaries inside every nested list into one value and then get that into list with others, so would get such values: Painted Wood, Mirror, Gold Leaf.
There won't be lists nested more levels and no more than two dictionaries inside them, so for e.g. from this list below would need to get such values: Painted Wood, Mirror, Varnished Wood, Gold Leaf.
p_mat_list = [
[{'name': 'Painted'}, {'name': 'Wood'}],
{'name': 'Mirror'},
[{'name': 'Varnished'}, {'name': 'Wood'}],
{'name': 'Gold Leaf'}
]
2 Answers 2
If you're open to bringing in an external library, you could use the collapse()
function from more-itertools. Use it something like this:
import more_itertools as mt
list(mt.collapse(p_mat_list, base_type=dict))
[{'name': 'Painted'},
{'name': 'Wood'},
{'name': 'Mirror'},
{'name': 'Gold Leaf'}]
Then in your case, you can just extract the value corresponding to 'name'
from each dict, instead of making a list of them.
>>> [d['name'] for d in mt.collapse(p_mat_list, base_type=dict)]
This has the advantage that you don't have to worry about how many levels of list nesting there are.
The best way would be to flatten the complex list you have a function like this :
def flatten(x):
if isinstance(x, dict) :
return [x]
elif isinstance(x, collections.Iterable) :
return [a for i in x for a in flatten(i)]
else:
return [x]
This function, takes your p_mat_list
as an argument and returns a single list of dictionaries.
get_list = flatten(p_mat_list)
product_materials = []
for material in get_list :
product_materials.append(material['name'])
Your product_materials
list :
['Painted', 'Wood', 'Mirror', 'Gold Leaf']
-
2Note that some consider it an antipattern to bind a lambda to a name. These sources claim that in these cases one should define a full-fledged named function.Andras Deak -- Слава Україні– Andras Deak -- Слава Україні2017年02月08日 00:26:51 +00:00Commented Feb 8, 2017 at 0:26
-
2"Some" being the official Python style-guide.juanpa.arrivillaga– juanpa.arrivillaga2017年02月08日 00:27:34 +00:00Commented Feb 8, 2017 at 0:27
-
@AndrasDeak How about now ?Jarvis– Jarvis2017年02月08日 00:46:42 +00:00Commented Feb 8, 2017 at 0:46
'Painted Wood'
as a single string, instead of'Painted'
and'Wood'
as separate strings? If so, it's inconsistent with your first example, and in that case I think we would need some more clarification on what you mean.