I have a string that needs to be split 3 ways and then into a list of dictionaries.
given_string = 'name:mickey,age:58|name:minnie,age:47,weight:60'
data = []
data = [value.split(',') for value in given_string.split('|')]
data = [['name:mickey', 'age:58'], ['name:minnie', 'age:47', 'weight:60']]
Now I want to split this one more time on the ':' and have the data contain a list of two dictionaries so that when I input say data[1][age], I get 47.
Basically, I think I want this for it to work:
data = [{'name': 'mickey', 'age': '58}, {'name': 'minnie', 'age': '47', 'weight': '60'}]
I believe that ultimately, data should be a list of dictionaries but once I split the string into two lists, I get confused in splitting it on the ':' and then converting the sublists to a dictionary.
You can do with a simple list comprehension
>>> [dict(x.split(':') for x in parts.split(','))
for parts in given_string.split('|')]
[{'age': '58', 'name': 'mickey'}, {'age': '47', 'name': 'minnie', 'weight': '60'}]
Nest harder.
>>> [ dict(y.split(':') for y in x.split(',')) for x in 'name:mickey,age:58|name:minnie,age:47,weight:60'.split('|')]
[{'age': '58', 'name': 'mickey'}, {'age': '47', 'name': 'minnie', 'weight': '60'}]
given_string = 'name:mickey,age:58|name:minnie,age:47,weight:60'
data = [value.split(',') for value in given_string.split('|')]
y=[] # make a empty list
for i in data:
z={}
for v in range(len(i)):
b=i[v].split(":") # ['name", "mickey', 'age","58"]
z[b[0]]=b[1] # adding keys and values in dictionary z
y.append(z) # adding dictionary to the list
Related
I have this list of dicts:
[{'name': 'aly', 'age': '104'},
{'name': 'Not A name', 'age': '99'}]
I want the name value to be the key and the age value to be the value of new dict.
Expected output:
['aly' : '104', 'Not A name': '99']
If you want output to be single dict, you can use dict comprehension:
output = {p["name"]: p["age"] for p in persons}
>>> {'aly': '104', 'Not A name': '99'}
If you want output to be list of dicts, you can use list comprehension:
output = [{p["name"]: p["age"]} for p in persons]
>>> [{'aly': '104'}, {'Not A name': '99'}]
You can initialize the new dict, iterate through the list and add to the new dict:
lst = [{'name': 'aly', 'age': '104'}, {'name': 'Not A name', 'age': '99'}]
newdict = {}
for item in lst:
newdict[item['name']] = item['age']
This will help you:
d = [
{'name': 'aly', 'age': '104'},
{'name': 'Not A name', 'age': '99'}
]
dict([i.values() for i in d])
# Result
{'aly': '104', 'Not A name': '99'}
# In case if you want a list of dictionary, use this
[dict([i.values() for i in d])]
# Result
[{'aly': '104', 'Not A name': '99'}]
Just a side note:
Your expected answer looks like a list (because of [ ]) but values inside the list are dictionary (key:value) which is invalid.
Here is the easiest way to convert the new list of dicts
res = list(map(lambda data: {data['name']: data['age']}, d))
print(res)
I have a list of strings which contains spanish-recipesĀ“s ingredients and its quantities and I would like to get a list of dictionaries splitting every ingredient, unit and quantity.
This is the list:
ingredients=[
'50',
'ccs',
'aceite',
'1',
'hoja',
'laurel',
'\n',
'1',
'cabeza',
'ajos',
'1',
'vaso',
'vino',
'1,5',
'kilos',
'conejo',
'\n',
...]
I would like to get a dict like this:
my_dic=[
{"name":"aceite" ,"qt":50 ,"unit": "ccs"},
{"name":"laurel" ,"qt":1 ,"unit": "hoja"},
{"name":"ajos" ,"qt":1 ,"unit": "cabeza"},
{"name":"vino" ,"qt":1 ,"unit": "vaso"},
{"name":"conejo" ,"qt":1,5 ,"unit": "kilos"},
...]
I have been trying things but it was all a disaster.
Any ideas?
Thanks in advance!!
So first, you want to remove the newlines from your original list:
ingredients = [i for i in ingredients if i is not '\n']
Then, each ingredient name is every third element in the ingredients list starting from the third element. Likewise for the quantity and unit, starting from the second and first elements, respectively:
names = ingredients[2::3]
units = ingredients[1::3]
qts = ingredients[::3]
Then, iterate through these lists and construct the data structure you specified (which is not actually a dict but a list of dicts):
my_list = []
for i in range(len(names)):
my_dict = {"name":names[i],"qt":qts[i],"unit":units[i]}
my_list.append(my_dict)
There are a lot of ways to compress all of the above, but I have written it for comprehensibility.
This doesn't produce a dictionary, but it does give you the output that you specify in the question:
# Strip out the \n values (can possibly do this with a .strip() in the input stage)
ingredients = [value for value in ingredients if value != '\n']
labels = ['qt', 'unit', 'name']
my_dic = [dict(zip(labels, ingredients[i:i+3])) for i in range(0, len(ingredients), 3)]
my_dic contains:
[{'qt': '50', 'unit': 'ccs', 'name': 'aceite'},
{'qt': '1', 'unit': 'hoja', 'name': 'laurel'},
{'qt': '1', 'unit': 'cabeza', 'name': 'ajos'},
{'qt': '1', 'unit': 'vaso', 'name': 'vino'},
{'qt': '1,5', 'unit': 'kilos', 'name': 'conejo'}]
You can clean you list with filter to remove the \n characters and then zip() it together to collect your items together. This makes a quick two-liner:
l = filter(lambda w: w != '\n', ingredients)
result = [{'name': name, 'qt':qt, 'unit': unit}
for qt, unit, name in zip(l, l, l)]
result:
[{'name': 'aceite', 'qt': '50', 'unit': 'ccs'},
{'name': 'laurel', 'qt': '1', 'unit': 'hoja'},
{'name': 'ajos', 'qt': '1', 'unit': 'cabeza'},
{'name': 'vino', 'qt': '1', 'unit': 'vaso'},
{'name': 'conejo', 'qt': '1,5', 'unit': 'kilos'}]
How about:
ingredients = (list)(filter(lambda a: a != '\n', ingredients))
ing_organized = []
for i in range (0, len(ingredients) , 3):
curr_dict = {"name": ingredients[i+2] ,"qt": ingredients[i] ,"unit": ingredients[i+1]}
ing_organized.append(curr_dict)
I just removed '\n' elements from the list as they didn't seem to have meaning.
lst = [['111', 'kam'],['222', 'Van']]
Header = ['ID', 'Name']
I want to convert the above list to dictionary based on the Headers. I can do this simply using for loop by taking each element in loop and append to some new list one by one.
But, I want to achieve the same without using loop to prevent from performance issue.
Is there any way to do that?
Expected Output:
[{'ID' : '111', 'Name' : 'Kam'},{'ID' : '222', 'Name' : 'Van'}]
You can use a list comprehension:
lst = [['111', 'kam'],['222', 'Van']]
Header = ['ID', 'Name']
result = [dict(zip(Header, row)) for row in lst]
print(result)
Output:
[{'ID': '111', 'Name': 'kam'}, {'ID': '222', 'Name': 'Van'}]
Please help me. I have dataset like this:
my_dict = { 'project_1' : [{'commit_number':'14','name':'john'},
{'commit_number':'10','name':'steve'}],
'project_2' : [{'commit_number':'12','name':'jack'},
{'commit_number':'15','name':'anna'},
{'commit_number':'11','name':'andy'}]
}
I need to sort the dataset based on the commit number in descending order and make it into a new list by ignoring the name of the project using python. The list expected will be like this:
ordered_list_of_dict = [{'commit_number':'15','name':'anna'},
{'commit_number':'14','name':'john'},
{'commit_number':'12','name':'jack'},
{'commit_number':'11','name':'andy'},
{'commit_number':'10','name':'steve'}]
Thank you so much for helping me.
Extract my_dict's values as a list of lists*
Join each sub-list together (flatten dict_values) to form a flat list
Sort each element by commit_number
*list of lists on python2. On python3, a dict_values object is returned.
from itertools import chain
res = sorted(chain.from_iterable(my_dict.values()),
key=lambda x: x['commit_number'],
reverse=True)
[{'commit_number': '15', 'name': 'anna'},
{'commit_number': '14', 'name': 'john'},
{'commit_number': '12', 'name': 'jack'},
{'commit_number': '11', 'name': 'andy'},
{'commit_number': '10', 'name': 'steve'}]
On python2, you'd use dict.itervalues instead of dict.values to the same effect.
Coldspeed's answer is great as usual but as an alternative, you can use the following:
ordered_list_of_dict = sorted([x for y in my_dict.values() for x in y], key=lambda x: x['commit_number'], reverse=True)
which, when printed, gives:
print(ordered_list_of_dict)
# [{'commit_number': '15', 'name': 'anna'}, {'commit_number': '14', 'name': 'john'}, {'commit_number': '12', 'name': 'jack'}, {'commit_number': '11', 'name': 'andy'}, {'commit_number': '10', 'name': 'steve'}]
Note that in the list-comprehension you have the standard construct for flattening a list of lists:
[x for sublist in big_list for x in sublist]
I'll provide the less-pythonic and more reader-friendly answer.
First, iterate through key-value pairs in my_dict, and add each element of value to an empty list. This way you avoid having to flatten out a list of lists:
commits = []
for key, val in my_dict.items():
for commit in val:
commits.append(commit)
which gives this:
In [121]: commits
Out[121]:
[{'commit_number': '12', 'name': 'jack'},
{'commit_number': '15', 'name': 'anna'},
{'commit_number': '11', 'name': 'andy'},
{'commit_number': '14', 'name': 'john'},
{'commit_number': '10', 'name': 'steve'}]
Then sort it in descending order:
sorted(commits, reverse = True)
This will sort based on 'commit_number' even if you don't specify it because it comes alphabetically before 'name'. If you want to specify it for the sake of defensive coding, this would be fastest and cleanest way, to the best of my knowledge :
from operator import itemgetter
sorted(commits, key = itemgetter('commit_number'), reverse = True)
I have a long list of dictionaries that for the most part do not overlap. However, some of the dictionaries have the same 'Name' field and I'd only like unique names in the list of dictionaries. I'd like the first occurrence of the name to be the one that stays and any thereafter be deleted from the list.
I've put a short list below to illustrate the scenario:
myList = [
{'Name':'John', 'Age':'50', 'Height':'70'},
{'Name':'Kathy', 'Age':'43', 'Height':'65'},
{'Name':'John','Age':'46','Height':'68'},
{'Name':'John','Age':'50','Height':'72'}
]
I'd like this list to return the first 'John' and Kathy, but not the second or third Johns and their related information.
An acceptable, but not optimal solution would also be not having dictionaries with the same name next to each other.
You could run over the list and keep a set of unique names. Every time you encounter a new name (i.e., a name that isn't in the set), you add it to the set and the respective dict to the result:
def uniqueNames(dicts):
names = set()
result = []
for d in dicts:
if not d['Name'] in names:
names.add(d['Name'])
result.append(d)
return result
You can easily write a for-loop for this.
def getName(name):
'''Gets first occurence of name in list of dicts.'''
for i in myList:
if i['Name'] == name:
return i
Initial list:
my_list = [
{'Name':'John', 'Age':'50', 'Height':'70'},
{'Name':'Kathy', 'Age':'43', 'Height':'65'},
{'Name':'John','Age':'46','Height':'68'},
{'Name':'John','Age':'50','Height':'72'}
]
The logical (potentially newbie-friendlier) way:
names = set()
new_list = []
for d in my_list:
name = d['Name']
if name not in names:
new_list.append(d)
names.add(d['Name'])
print new_list # [{'Age': '50', 'Name': 'John', 'Height': '70'}, {'Age': '43', 'Name': 'Kathy', 'Height': '65'}]
A one-liner way:
new_list = {d['Name']: d for d in reversed(my_list)}.values()
print new_list # [{'Age': '43', 'Name': 'Kathy', 'Height': '65'}, {'Age': '50', 'Name': 'John', 'Height': '70'}]
Note: The one-liner will contain the first occurrence of each name, but it will return an arbitrarily ordered list.