create new dictionary based on keys and split the dictionary values - python-3.x

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.

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)

extract dictionary elements from nested list in python

I have a question.
I have a nested list that looks like this.
x= [[{'screen_name': 'BreitbartNews',
'name': 'Breitbart News',
'id': 457984599,
'id_str': '457984599',
'indices': [126, 140]}],
[],
[],
[{'screen_name': 'BreitbartNews',
'name': 'Breitbart News',
'id': 457984599,
'id_str': '457984599',
'indices': [98, 112]}],
[{'screen_name': 'BreitbartNews',
'name': 'Breitbart News',
'id': 457984599,
'id_str': '457984599',
'indices': [82, 96]}]]
There are some empty lists inside the main list.
What I am trying to do is to extract screen_name and append them as a new list including the empty ones (maybe noting them as 'null').
y=[]
for i in x :
for j in i :
if len(j)==0 :
n = 'null'
else :
n = j['screen_name']
y.append(n)
I don't know why the code above outputs a list,
['BreitbartNews',
'BreitbartNews',
'BreitbartNews',
'BreitbartNews',
'BreitbartNews']
which don't reflect the empty sublist.
Can anyone help me how I can refine my code to make it right?
You are checking the lengths of the wrong lists. Your empty lists are in the i variables.
The correct code would be
y=[]
for i in x :
if len(i) == 0:
n = 'null'
else:
n = i[0]['screen_name']
y.append(n)
It may help to print(i) in each iteration to better understand what is actually happening.

Python how to make string from file to dictionary in list

I have file with format string like below. With always six field and sometime user wrong typing for some field so I try to use regex to match the field.
name : Luke Skywalker
hp. : 0813412345678
address : Jl. Gagak 3 No.5 Bandung Selatan
product : TSirt Starwars
quantity : 1
note : size L
name : Qui-Gon Jinn
hp. : 08156898234567
address : Jl. Tatoon No.142 Bandung Barat
product : pants Chino Krem
quantity : 1
note : size L
name : Obi-Wan Kenobi
hp. : 08877763212312
address : Jl. Pemuda No.66 Bandung Selatan
product : TSirt Starwars
quantity : 1
note : size L
And I want make dictionary in the list with format like this.
[
{
'name': 'Luke Skywalker',
'mobile': '0813412345678',
'address': 'Jl. Gagak 3 No.5 Bandung Selatan',
'product': 'TSirt Starwars',
'quantity': '1',
'note': 'size L'
},
{
'name': 'Qui-Gon Jinn',
'mobile': '08156898234567',
'address': 'Jl. Tatoon No.142 Bandung Barat',
'product': 'pants Chino Krem',
'quantity': '1',
'note': 'size L'
},
{
'name': 'Obi-Wan Kenobi',
'mobile': '08877763212312',
'address': 'Jl. Pemuda No.66 Bandung Selatan',
'product': 'TSirt Starwars',
'quantity': '1',
'note': 'size L'
}
]
So far I have been success with this code:
# -*- coding: utf-8 -*-
import re
_lst = []
with open("filetoread.txt", "r") as read_file:
_tmp_name = []
_tmp_mobile = []
_tmp_alamat = []
_tmp_produk = []
_tmp_jml = []
_tmp_note = []
for i in read_file:
if i is not "\n":
_splt = i.split(":")
if re.compile(r"nam[a|e]", re.I).match(_splt[0].strip()):
_tmp_name.append({"name":_splt[1].strip()})
if re.compile(r"^hp(\.\s)?|^hand\w|telp(\.\s)?", re.I).match(_splt[0].strip()):
_tmp_mobile.append({"mobile":_splt[1].strip()})
if re.compile(r"alamat|address", re.I).match(_splt[0].strip()):
_tmp_alamat.append({"addredd":_splt[1].strip()})
if re.compile(r"produk|item", re.I).match(_splt[0].strip()):
_tmp_produk.append({"product":_splt[1].strip()})
if re.compile(r"jml(\.\s)?|jumlah|total", re.I).match(_splt[0].strip()):
_tmp_jml.append({"quantity":_splt[1].strip()})
if re.compile(r"note", re.I).match(_splt[0].strip()):
_tmp_note.append({"note":_splt[1].strip()})
_zip = list(zip(_tmp_name, _tmp_mobile, _tmp_alamat, _tmp_produk, _tmp_jml, _tmp_note))
l = []
for z in _zip:
d = {}
for i in z:
d.update(i)
l.append(d)
print(l)
But I'm not really sure with this code. Is there a better way to do it in the python way which is simpler and clever.
Thanks advance.
Hi i have a simple solution for your problem but you need to change names after dictionary make
result = list()
tmp_obj = dict()
for line in open('input.txt', 'r').readlines():
if len(line) > 1:
key, value = line.split(':')
tmp_obj[key.strip()] = value.strip()
else:
result.append(tmp_obj)
tmp_obj = dict()
print(result)

Make key lowercase in List of Dictionaries (Python3)

Been looking through Stackoverflow and documentations for 2 days now, I am a beginner, and I just can't progress. I am using Python 3.8.
I have a list of dictionaries:
books = [{'Type': 'Book', 'Date': '2011', 'Publication Year': '2011', 'Place Published': 'New York', 'Publisher': 'Simon & Schuster', 'Author': 'Walter Isaacson', 'ISBN': '978-1-4516-4853-9', 'Title': 'Test Steve Jobs'}, {'Type': 'Book', 'Date': '2001', 'Publication Year': '2001', 'Place Published': 'Oxford', 'Publisher': 'Oxford University press', 'Author': 'Peter Hall', 'ISBN': '978-0-19-924775-2', 'Title': 'Test Varieties of capitalism: the institutional foundations of comparative advantage'}]
print(books)
I want to make the key "Type" into a lowercase "type".
But with the following List Comprehension it somehow makes the key to a value and vice versa.
lower_list = [ { v:k.lower() for k,v in d.items() } for d in books ]
print(lower_list)
I end up with [{'Book': 'type',.... when it should be [{'type': 'Book',....
I am struggling with understanding the list comprehension syntax still, so would be grateful for 1. somebody explaining what my list comprehension does in plain English and 2. how to change it to achieve what I am looking for. :)
Thank you!
So your first problem:
lower_list = [ { k.lower():v for k,v in d.items() } for d in books ] ?
You was inverting key and values.
Your last question how to skip lowercasing the ISBN key:
[ { k if k is "ISBN" else k.lower():v.lower() for k,v in d.items()} for d in books ]
But you should consider using a for loop: if your need more operations or conditions, it would start to be difficult to modify further.
my_final_books = []
for d in books:
for k,v in d.items():
if k is "ISBN":
key = k
else:
key = k.lower()
# or ternary form key = k if k is "ISBN" else k.lower()
my_final_books.append({key:v})
# do more logic here

Create a list of maps from multiple lists

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.

Resources