Create dictionary comprehension using multiple lists - python

I am a newbie in python.
I have 3 lists (price_list/address_list/link_list), I am trying to combine them in one dictionary with this structure:
{
{
"price":price,
"address":address,
"link":link,
},
{
"price":price,
"address":address,
"link":link,
}
}
I am able to create the list with nested dictionaries but not dictionary with nested dictionary
my_dict = [{'price': price, 'address': address, 'link': link} for price, address, link in zip(price_list, address_list, link_list)]
What would be the equivalent please?

A dictionary is essentially a data structure that maps certain values to a collection of keys. Your inner dictionary seems to be fine. You have defined a key and a value. However, in your outer dictionary, you seem to be only having list of values (the inner dicts) and no key to associate them with.
For instance, I have added 'key1' and 'key2' to demonstrate that your outer dictionary needs to have keys defined.
{
"key1": {
"price":price,
"address":address,
"link":link,
},
"key2": {
"price":price,
"address":address,
"link":link,
}
}
So what you're asking is not exactly possible.
However, if you manage to find some keys for your outer dictionary, then you can iterate over the list of dicts that you already have and then assign the elements of the list against some key in the outer dict.
Something like this should work if you're looking for a one-liner:
my_dict = {i: j for i,j in zip(range(len(price_list)), [{'price': price, 'address': address, 'link': link} for price, address, link in zip(price_list, address_list, link_list)])}
It would return:
{
0: {'price': price1, 'address': 'addr1', 'link': 'link1'},
1: {'price': price2, 'address': 'addr2', 'link': 'link2'},
2: {'price': price3, 'address': 'addr3', 'link': 'link3'}
}

Unlike List, Dictionary is like a JSON object, i.e. always has a key-value pair. So you must specify a key, like this:
myDict = {
"dict1":{ // Key
"price":price, // Values
"address":address,
"link":link,
},
"dict2":{ // Key
"price":price, // Values
"address":address,
"link":link,
}
}
Assuming all three lists you have are of the same length, you can do this to get a nested dictionary:
myDict = {}
for i in range(len(price_list)): // You can use any other list instead.
myDict[i] = { // Or whatever key suites you.
"price": price_list[i]
"address": addess_list[i]
"link": link_list[i]
}

You cannot create a Dictionary with nested Dictionaries like you created one with the list.
This is due to the fact that every element in a dictionary must have a key.
If you want to create a nested dictionary then the outermost dictionary (containing dictionaries) must have keys for every dictionary.
{
1 :{
"price":price,
"address":address,
"link":link,
},
2 :{
"price":price,
"address":address,
"link":link,
}
}
Something like this where 1, 2 are keys.
to do this simply initialize a variable with 1
then after adding values increment the variable
for eg
in loop()
i = 1
dic = {}
dic[i] = "whatever"
i += 1

Related

shorter way to delete key from a dictionary

I have wanted to delete the taste key from the line_items dict list of the entire dictionary list. the code is given below
orders = [
{
'order_id' : 1,
'line_items': [
{
'product_id': 2,
'product_name' : 'mango',
'taste' : 'sweet',
},
{
'product_id':3,
'product_name': 'grape',
'taste': 'sweet & sour',
}
],
},
{
'order_id' : 2,
'line_items': [
{
'product_id': 4,
'product_name' : 'lime',
'taste' : 'sour',
}
]
},
]
I have already done it. and this is my solution.
delitems = ['taste']
for order in orders:
for item in order["line_items"]:
for delkeys in delitems:
item.pop(delkeys)
But I think it is a bad code and wanted to know if is there any way to shorting my code
with dict comprehension or another way?
Slightly more natural than using dict.pop when you don't care about the value you're deleting would be to use the del statement:
del item[delkeys]
Obviously, this doesn't reduce the number of lines. If you're only ever deleting the one key, you don't need the delitems and the loop over it. If you don't mind hard-coding that "taste" is the key to delete, just do:
for order in orders:
for item in order["line_items"]:
del item["taste"]
While you could write a bunch of nested list comprehension and dictionary comprehensions to achieve the same effect in a single statement, it would be a lot harder to understand than your simple nested loop code.
for order in orders:
for item in order["line_items"]:
del item["taste"]

Update dicitonary key with every value from a list

Given this list:
pc = ['OferteConfigurabile_S2D_Rate',
'OferteConfigurabile_S2D_Rate_si_Discount',
'OferteConfigurabile_S2D_SimOnly_si_Discount',
'OferteConfigurabile_S2D_SimOnly',
'OferteConfigurabile_S2D_VMM_Rate']
And this dictionary:
lst = []
dataModel = {
'channel': 'RETAIL',
'searchType': 'MSISDN',
'searchValue': 727277696,
'configType': 'RETENTIE',
'scenarioName_PC': 'OferteConfigurabile_ServiceOnly',
'retention_option': '360_OFERTE_MOBILE',
'retention_flow': 'ConfigureazaOferte',
}
I want for every element in the 'pc' list to update dateModel['scenarioName_PC'] and store the resulting dictionary into a list but slightly changed by creating a new dict with a custom key and dataModel dictionary as its value
for i in pc:
dataModel['scenarioName_PC'] = i
lst.append({f"{dataModel['retention_option']}_{dataModel['retention_flow']}_{i}" : dataModel})
print(lst)
The problem is that when i print the list 'scenarioName_PC' key always has the last element from the iterated list, the dataModel dictionary dosen't save the value for every for loop iteration, it somehow only stores the last value in PC list
[
{
"360_OFERTE_MOBILE_ConfigureazaOferte_OferteConfigurabile_S2D_Rate":{
"channel":"RETAIL",
"searchType":"MSISDN",
"searchValue":727277696,
"configType":"RETENTIE",
"scenarioName_PC":"OferteConfigurabile_S2D_VMM_Rate",
"retention_option":"360_OFERTE_MOBILE",
"retention_flow":"ConfigureazaOferte"
}
},
{
"360_OFERTE_MOBILE_ConfigureazaOferte_OferteConfigurabile_S2D_Rate_si_Discount":{
"channel":"RETAIL",
"searchType":"MSISDN",
"searchValue":727277696,
"configType":"RETENTIE",
"scenarioName_PC":"OferteConfigurabile_S2D_VMM_Rate",
"retention_option":"360_OFERTE_MOBILE",
"retention_flow":"ConfigureazaOferte"
}
},
Expected result is a list with dataModel dictionary but for scenarioname_PC key to have every time 'i' as value.
[
{
"360_OFERTE_MOBILE_ConfigureazaOferte_OferteConfigurabile_S2D_Rate":{
"channel":"RETAIL",
"searchType":"MSISDN",
"searchValue":727277696,
"configType":"RETENTIE",
"scenarioName_PC":"OferteConfigurabile_S2D_Rate",
"retention_option":"360_OFERTE_MOBILE",
"retention_flow":"ConfigureazaOferte"
}
},
{
"360_OFERTE_MOBILE_ConfigureazaOferte_OferteConfigurabile_S2D_Rate_si_Discount":{
"channel":"RETAIL",
"searchType":"MSISDN",
"searchValue":727277696,
"configType":"RETENTIE",
"scenarioName_PC":"OferteConfigurabile_S2D_Rate_si_Discount",
"retention_option":"360_OFERTE_MOBILE",
"retention_flow":"ConfigureazaOferte"
}
},
while appending copy the dictionary object instead of just passing the dictionary. You are passing the dictionary reference which is being modified.
This should work.
import copy
for i in pc:
new_dataMode = copy.deepcopy(dataMode)
new_dataModel['scenarioName_PC'] = i
lst.append({f"{new_dataModel['retention_option']}_{new_dataModel['retention_flow']}_{i}" : new_dataModel})
print(lst)

How can I mitigate the error in Python Dictionary?

How do I access to visibilities?
I am trying like this: dev1['data']['results :visibilites ']
dev1 = {
"status": "OK",
"data": {
"results": [
{
"tradeRelCode": "ZT55",
"customerCode": "ZC0",
"customerName": "XYZ",
"tier": "null1",
"visibilites": [
{
"code": "ZS0004207",
"name": "Aabc Systems Co.,Ltd",
"siteVisibilityMap": {
},
"customerRef": "null1"
}
]
}
],
"pageNumber": 3,
"limit": 1,
"total": 186
}
}
You can use dev1['data']['results'][0]['visibilites'].
It will contain a list of one dictionary.
To access this dictionary directly, use dev1['data']['results'][0]['visibilites'][0]
dev['data'] represents a dictionary that has for key results.
You can access the item associated to results key (a list) using (dev1['data'])['results'].
To access the only member of this list, you use ((dev1['data'])['results'])[0].
This gives you a dictionary that has tradeRelCode, customerCode, customerName, tier and visibilites keys.
To access the item associated to visibilites key (a list), you have tu use (((dev1['data'])['results'])[0])['visibilites'].
To finally access the only dictionary contained in this list, you have tu use ((((dev1['data'])['results'])[0])['visibilites'])[0].
Parenthesis are here to show that python dig into each dictionary or list in order from left to right (python does not mind the parenthesis in the code, you can keep them if it is clearer for you.)
In your data structure use path
dev1['data']['results'][0]['visibilites']
Try this
dev1['data']['results'][0]['visibilites']
Reason:
This is a list -> dev1['data']['results']
So, access this -> dev1['data']['results'][0]
and then you obtain this ->
{'tradeRelCode': 'ZT55',
'customerCode': 'ZC0',
'customerName': 'XYZ',
'tier': 'null1',
'visibilites': [{'code': 'ZS0004207',
'name': 'Aabc Systems Co.,Ltd',
'siteVisibilityMap': {},
'customerRef': 'null1'}]}
and then you can have -> dev1['data']['results'][0]['visibilites']
which results in ->
[{'code': 'ZS0004207',
'name': 'Aabc Systems Co.,Ltd',
'siteVisibilityMap': {},
'customerRef': 'null1'}]
which is a list and you can index the first element which is another dictionary

Python - add a list of dictionary in a dictionary

So I have a dictionary called component and a list of dictionaries called allocations.
I want to be able to put the allocations under a component as a nested dictionary. kind of like so:
Allocations[
allocation1 : {
key : value
},
allocation2 {
key : value
}
]
My desired output:
Component1 : {
key:value
allocations : [allocation1 : {
key : value
}
,allocation2 : {
key : value
}
]
}
I came from Java, and i realize there is no append that I can use.
I tried this and obviously didnt work:
#allocate this under the selected component - DIDNT WORK
component["allocations"][] = allocation
How can I create a list of dictionaries in a dictionary?
Simply assign it:
component["allocations"] = some_list
For instance, if you want a new, empty one:
component["allocations"] = []
or:
component["allocations"] = list()
Then, manipulate the list as usual:
component["allocations"].append(some_object)

creating nested json objects from a list

I am attempting to understand how to take a list and convert that into a nested JSON object.
Expected Output
{
"Name1": [
{
"key": "value",
"key": "value",
"key": "value",
"key": "value"
}
],
}
So far my thinking as gone as follows, convert the list to dictionary using comprehension and splitting key value pairs.
list1 = ['key value', 'key value', 'key value']
dict1 = dict(item.split(" ") for item in list1)
I then thought converting that into a JSON object would be something similar to:
print json.loads(dict1)
However, Im not sure how to create the "Name1" parent key. And it seems google is being particularly helpful. Im sure there is something simple im missing, any pointers would be appreacited.
EDIT
Included a list for reference
You simply put them in another dictionary, and use a new list. So:
import json
list1 = ['key1 value1', 'key2 value2', 'key3 value3']
dict1 = {'Name1': [dict(item.split(" ",1) for item in list1)] }
# ^ dict ^ list with 1 element end list ^ ^ end dict
json.dumps(dict1)
And this produces:
>>> print(json.dumps(dict1))
{"Name1": [{"key2": "value2", "key3": "value3", "key1": "value1"}]}
Notes:
A dictionary can only contain different keys (both in JSON and Python);
You better split with .split(" ",1) since if the value contains spaces, these are all seen as still a single value.
dictionaries are unordered, so the order of th keys can be shuffled.

Categories