Create a list of maps from multiple lists - groovy

Given three lists:
l1 = ['Alice', 'Bob', 'Jane']
l2 = ['30', '40', '50']
l3 = ['NY', 'Berlin', 'Stockholm']
how do I create something like this:
[['name': 'Alice', 'age': '30', 'city': 'NY'],
['name': 'Bob', 'age': '40', 'city': 'Berlin'],
['name': 'Jane', 'age': '50', 'city': 'Stockholm']]
I've tried [l1,l2,l3].transpose() but it returns list of lists and I can't figure out how to add proper keys to collectEntries()
Thanks
Edit:
Not-so-elegant solution I came up with is this:
assert l1.length == l2.length
assert l2.length == l3.length
def mapping = []
l1.eachWithIndex {name, index ->
def obj = [:]
obj.name = name
obj.age = l2[index]
obj.city = l3[index]
mapping += obj
obj = []
};
But there must be a better way, right?

An attempt at solving this more elegantly.
The following code:
def l1 = ['Alice', 'Bob', 'Jane']
def l2 = ['30', '40', '50']
def l3 = ['NY', 'Berlin', 'Stockholm']
def result = [l1, l2, l3].transpose().collect { a, b, c ->
[name: a, age: b, city: c]
}
println result
when run, prints out:
~> groovy solution.groovy
[[name:Alice, age:30, city:NY],
[name:Bob, age:40, city:Berlin],
[name:Jane, age:50, city:Stockholm]]
~>
(formatting added for readability).
The trick here is the transpose method which the question already mentions - [l1, l2, l3].transpose() returns:
[[Alice, 30, NY], [Bob, 40, Berlin], [Jane, 50, Stockholm]]
and the collect { a, b, c -> expression uses groovy destructuring to assign [Alice, 30, NY] to a, b, c etc. This is essentially the same mechanics that make it possible to write:
def (a, b, c) = [1, 2, 3]
for multiple assignments.
collectEntries returns a map and since you want a list on the outermost level it's not really the right tool here.

Related

convert list of dictionary values in to list of values

Hi all below is my list of dictionary
a=[{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'},
{'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
iam expecting output like this
a={"Name":["dhaya","rishi],"Place":["pune","maharastra"],Designation:["fleetEngineer","Sr.Manager"]
"}
can any one assist
new_dict is the answer to the question you posted. Its the smallest and simplest.
b = list(a[0].keys())
new_dict = {}
for x in b:
new_dict[x] = [l[x] for l in a]
print('My expected dictionary',new_dict)
One can use nested for loops for this:
inputList = [{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'}, {
'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
outputDict = {}
for origDict in inputList:
for key, val in origDict.items():
if key in outputDict:
outputDict[key].append(val)
else:
outputDict[key] = [val]
print(outputDict)
a=[{'Name': 'dhaya', 'Place': 'pune', 'Designation': 'fleetEngineer'}, {'Name': 'rishi', 'Place': 'maharastra', 'Designation': 'Sr.Manager'}]
Name = []
Place = []
Designation = []
for ele in a:
Name.append(ele["Name"])
Place.append(ele["Place"])
Designation.append(ele["Designation"])
new_a = {}
new_a['Name'] = Name
new_a['Place'] = Place
new_a["pune"] = Designation
print(new_a)

create new dictionary based on keys and split the dictionary values

I am relatively new to python programming. I was trying some challenges in online to thorough my programming skills. I got stuck with the below code. Please someone help here.
ress = {'product': ['Mountain Dew Spark', 'pepsi'], 'quantity': ['7', '5']}
prods_list = []
prods_dict = {}
for k , v in ress.items():
if "product" in k:
if len(ress['product']) > 1:
entity_names = {}
entity_list = []
for i in range(len(ress['product'])):
prod = "product_" + str(i)
entity_names['product'] = ress['product'][i]
entity_names['quantity'] = ress['quantity'][i]
entity_list.append(entity_names)
prods_dict[prod] = entity_list
prods_list.append(prods_dict)
print(prods_list)
i am expecting output as below
Expected output:
[{"product_0":
{"quantity" : "7",
"product" : "mountain dew spark"}
},
{"product_1" : {
"quantity" : "5",
"product" : "pepsi"
}}]
Actual output:
[{'product_0': [{'product': 'pepsi', 'quantity': '5'},
{'product': 'pepsi', 'quantity': '5'}],
'product_1': [{'product': 'pepsi', 'quantity': '5'},
{'product': 'pepsi', 'quantity': '5'}]}]
Please note i want my code work for single values as well like ress = {'product': ['Mountain Dew Spark'], 'quantity': ['7']}
This is one way you can achieve it with regular loops:
ress = {'product': ['Mountain Dew Spark', 'pepsi'], 'quantity': ['7', '5']}
prods_list = []
for key, value in ress.items():
for ind, el in enumerate(value):
prod_num = 'product_' + str(ind)
# If this element is already present
if (len(prods_list) >= ind + 1):
# Add to existing dict
prods_list[ind][prod_num][key] = el
else:
# Otherwise - create a new dict
prods_list.append({ prod_num : { key : el } })
print(prods_list)
The first loop goes through the input dictionary, the second one through each of its lists. The code then determines if a dictionary for that product is already in the output list by checking the output list length. If it is, the code simply appends new inner dict for that product. If it is not - the code creates an outer dict for that product - and an inner one for this particular value set.
Maybe using a list comprehension along with enumerate and zip might be easier:
>>> res = {'product': ['Mountain Dew Spark', 'pepsi'], 'quantity': ['7', '5']}
>>> prods_list = [
... {f'product_{i}': {'quantity': int(q), 'product': p.lower()}}
... for i, (q, p) in enumerate(zip(res['quantity'], res['product']))
... ]
>>> prods_list
[{'product_0': {'quantity': 7, 'product': 'mountain dew spark'}}, {'product_1': {'quantity': 5, 'product': 'pepsi'}}]
This assumes that there will be no duplicate product entries. In that case, you would need to use a traditional for loop.

How to extract values based on keys from a list of `dict` objects in Python

I have a list sample_list looks like this:
[{'ID': '123456', 'price': '1.111'}, {'ID': '987654', 'price': '200.888'}, {'ID': '789789', 'price': '0.212'},{..},...]
It contains multiple dict object, now I want to write a function that takes a list of ID as inputs and return the corresponding price, something like:
def mapping_data(ids: list) -> map:
mapping_data['123456'] = '1.111
return mapping_data
What's the easiest way to achieve this?
You can use simple list_comprehension with if condition:
def mapping_data(ids):
return [d['price'] for id in ids for d in l if d['ID'] == id]
Complete code:
l = [{'ID': '123456', 'price': '1.111'}, {'ID': '987654',
'price': '200.888'}, {'ID': '789789', 'price': '0.212'}]
def mapping_data(ids):
return [d['price'] for id in ids for d in l if d['ID'] == id]
mapping_data(['987654', '123456']) #prints ['200.888', '1.111']
You can also use dict_comprehension if you need id details:
def mapping_data(ids):
return {id:d['price'] for id in ids for d in l if d['ID'] == id}
# prints {'987654': '200.888', '123456': '1.111'}
Better Alternative:
Dict_comprehension:
def mapping_data(ids):
return {i['ID']:i['price'] for i in l if i['ID'] in ids}
mapping_data(['987654', '123456'])

Conditional list comprehension with 2 lists

Is it possible to convert this yield-function into a (more concise) list comprehension?
l1 = ['ID1', 'ID2', 'ID3', 'sum', 'sum', 'sum']
l2 = ['', '', '', 'Val1', 'Val2', 'Val3']
def getList(l1, l2):
for i in range(len(l1)):
yield l2[i] if l1[i] == 'sum' else l1[i]
print(list(getList(l1, l2)))
Thx & kind regards
Yes, you can write the loop as a list comprehension like so:
def getList(l1, l2)
return [b if b == 'sum' else a for a, b in zip(l1, l2)]
Note that the function is no longer a generator, since it does not yield single values but returns a list.
This may be what you're looking for:
list_comp = [i for i in (l1+l2) if i not in ['', 'sum']]
print(list_comp)
#['ID1', 'ID2', 'ID3', 'Val1', 'Val2', 'Val3']
You could also use map() for this:
def get_list(l1, l2):
return list(map(lambda x, y: y if y == 'sum' else x, l1, l2))

Create dictionary from values found in two other dictionaries

Issue: I want to compare the two dictionaries - alist & blist - and use the values to create a new dictionary (clist).
****Please note that the alist is a result of comparing two other dicts****
The final solution would be:
clist = {'actual_url': ['bizname', 'buyer', 'date', 'Amount']
my attempt at doing this is below
Thanks for your help as I am really stuck!
alist = {acct_number': ['file_no', 'url', 'user', ['Biz_name', 'tool', 'date', 'amt']]}
blist = {acct_number: ['actual_case', 'actual_url']}
clist={}
for k, v in alist.item():
for k, v in blist.item():
if v==v:
clist[v]:alist[v]
print(clist)
If the 'actual_url' is always the second item in the list, you can do this:
clist = {}
clist[blist['acct_number'][1]] = alist['acct_number']
To iterate over multiple items in alist:
alist = {
'12345': ['2', 'my_url.com', 'James', ['James corp', 'a', '100', '30']],
'35299': ['5', 'another_url.org', 'Carrie', ['Carrie corp', 'b', '60', '20']],
}
blist = {
'12345': ['actual_case', 'my_url.com'],
'35299': ['actual_case', 'another_url.org'],
}
clist = {}
for acct_number, value in alist.items():
clist[blist[acct_number][1]] = value

Resources